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 /* Gets the affine map from the original cell to each subcell */ 28 PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 29 { 30 PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ; 31 PetscInt dim, s; 32 PetscErrorCode ierr; 33 34 PetscFunctionBegin; 35 switch (refiner) { 36 case REFINER_NOOP: break; 37 case REFINER_SIMPLEX_2D: 38 /* 39 2 40 |\ 41 | \ 42 | \ 43 | \ 44 | C \ 45 | \ 46 | \ 47 2---1---1 48 |\ D / \ 49 | 2 0 \ 50 |A \ / B \ 51 0---0-------1 52 */ 53 dim = 2; 54 if (numSubcells) *numSubcells = 4; 55 if (v0) { 56 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 57 /* A */ 58 v[0+0] = -1.0; v[0+1] = -1.0; 59 j[0+0] = 0.5; j[0+1] = 0.0; 60 j[0+2] = 0.0; j[0+3] = 0.5; 61 /* B */ 62 v[2+0] = 0.0; v[2+1] = -1.0; 63 j[4+0] = 0.5; j[4+1] = 0.0; 64 j[4+2] = 0.0; j[4+3] = 0.5; 65 /* C */ 66 v[4+0] = -1.0; v[4+1] = 0.0; 67 j[8+0] = 0.5; j[8+1] = 0.0; 68 j[8+2] = 0.0; j[8+3] = 0.5; 69 /* D */ 70 v[6+0] = 0.0; v[6+1] = -1.0; 71 j[12+0] = 0.0; j[12+1] = -0.5; 72 j[12+2] = 0.5; j[12+3] = 0.5; 73 for (s = 0; s < 4; ++s) { 74 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 75 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 76 } 77 } 78 break; 79 case REFINER_HEX_2D: 80 /* 81 3---------2---------2 82 | | | 83 | D 2 C | 84 | | | 85 3----3----0----1----1 86 | | | 87 | A 0 B | 88 | | | 89 0---------0---------1 90 */ 91 dim = 2; 92 if (numSubcells) *numSubcells = 4; 93 if (v0) { 94 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 95 /* A */ 96 v[0+0] = -1.0; v[0+1] = -1.0; 97 j[0+0] = 0.5; j[0+1] = 0.0; 98 j[0+2] = 0.0; j[0+3] = 0.5; 99 /* B */ 100 v[2+0] = 0.0; v[2+1] = -1.0; 101 j[4+0] = 0.5; j[4+1] = 0.0; 102 j[4+2] = 0.0; j[4+3] = 0.5; 103 /* C */ 104 v[4+0] = 0.0; v[4+1] = 0.0; 105 j[8+0] = 0.5; j[8+1] = 0.0; 106 j[8+2] = 0.0; j[8+3] = 0.5; 107 /* D */ 108 v[6+0] = -1.0; v[6+1] = 0.0; 109 j[12+0] = 0.5; j[12+1] = 0.0; 110 j[12+2] = 0.0; j[12+3] = 0.5; 111 for (s = 0; s < 4; ++s) { 112 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 113 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 114 } 115 } 116 break; 117 case REFINER_HEX_3D: 118 /* 119 Bottom (viewed from top) Top 120 1---------2---------2 7---------2---------6 121 | | | | | | 122 | B 2 C | | H 2 G | 123 | | | | | | 124 3----3----0----1----1 3----3----0----1----1 125 | | | | | | 126 | A 0 D | | E 0 F | 127 | | | | | | 128 0---------0---------3 4---------0---------5 129 */ 130 break; 131 dim = 3; 132 if (numSubcells) *numSubcells = 8; 133 if (v0) { 134 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 135 /* A */ 136 v[0+0] = -1.0; v[0+1] = -1.0; v[0+2] = -1.0; 137 j[0+0] = 0.5; j[0+1] = 0.0; j[0+2] = 0.0; 138 j[0+3] = 0.0; j[0+4] = 0.5; j[0+5] = 0.0; 139 j[0+6] = 0.0; j[0+7] = 0.0; j[0+8] = 0.5; 140 /* B */ 141 v[3+0] = -1.0; v[3+1] = 0.0; v[3+2] = -1.0; 142 j[9+0] = 0.5; j[9+1] = 0.0; j[9+2] = 0.0; 143 j[9+3] = 0.0; j[9+4] = 0.5; j[9+5] = 0.0; 144 j[9+6] = 0.0; j[9+7] = 0.0; j[9+8] = 0.5; 145 /* C */ 146 v[6+0] = 0.0; v[6+1] = 0.0; v[6+2] = -1.0; 147 j[18+0] = 0.5; j[18+1] = 0.0; j[18+2] = 0.0; 148 j[18+3] = 0.0; j[18+4] = 0.5; j[18+5] = 0.0; 149 j[18+6] = 0.0; j[18+7] = 0.0; j[18+8] = 0.5; 150 /* D */ 151 v[9+0] = 0.0; v[9+1] = -1.0; v[9+2] = -1.0; 152 j[27+0] = 0.5; j[27+1] = 0.0; j[27+2] = 0.0; 153 j[27+3] = 0.0; j[27+4] = 0.5; j[27+5] = 0.0; 154 j[27+6] = 0.0; j[27+7] = 0.0; j[27+8] = 0.5; 155 /* E */ 156 v[12+0] = -1.0; v[12+1] = -1.0; v[12+2] = 0.0; 157 j[36+0] = 0.5; j[36+1] = 0.0; j[36+2] = 0.0; 158 j[36+3] = 0.0; j[36+4] = 0.5; j[36+5] = 0.0; 159 j[36+6] = 0.0; j[36+7] = 0.0; j[36+8] = 0.5; 160 /* F */ 161 v[15+0] = 0.0; v[15+1] = -1.0; v[15+2] = 0.0; 162 j[45+0] = 0.5; j[45+1] = 0.0; j[45+2] = 0.0; 163 j[45+3] = 0.0; j[45+4] = 0.5; j[45+5] = 0.0; 164 j[45+6] = 0.0; j[45+7] = 0.0; j[45+8] = 0.5; 165 /* G */ 166 v[18+0] = 0.0; v[18+1] = 0.0; v[18+2] = 0.0; 167 j[54+0] = 0.5; j[54+1] = 0.0; j[54+2] = 0.0; 168 j[54+3] = 0.0; j[54+4] = 0.5; j[54+5] = 0.0; 169 j[54+6] = 0.0; j[54+7] = 0.0; j[54+8] = 0.5; 170 /* H */ 171 v[21+0] = -1.0; v[21+1] = 0.0; v[21+2] = 0.0; 172 j[63+0] = 0.5; j[63+1] = 0.0; j[63+2] = 0.0; 173 j[63+3] = 0.0; j[63+4] = 0.5; j[63+5] = 0.0; 174 j[63+6] = 0.0; j[63+7] = 0.0; j[63+8] = 0.5; 175 for (s = 0; s < 8; ++s) { 176 DMPlex_Det3D_Internal(&detJ, &j[s*dim*dim]); 177 DMPlex_Invert3D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 178 } 179 } 180 default: 181 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 182 } 183 if (v0) {*v0 = v; *jac = j; *invjac = invj;} 184 PetscFunctionReturn(0); 185 } 186 187 PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 188 { 189 PetscErrorCode ierr; 190 191 PetscFunctionBegin; 192 ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr); 193 PetscFunctionReturn(0); 194 } 195 196 /* Should this be here or in the DualSpace somehow? */ 197 PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside) 198 { 199 PetscReal sum = 0.0; 200 PetscInt d; 201 202 PetscFunctionBegin; 203 *inside = PETSC_TRUE; 204 switch (refiner) { 205 case REFINER_NOOP: break; 206 case REFINER_SIMPLEX_2D: 207 for (d = 0; d < 2; ++d) { 208 if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 209 sum += point[d]; 210 } 211 if (sum > 1.0e-10) {*inside = PETSC_FALSE; break;} 212 break; 213 case REFINER_HEX_2D: 214 for (d = 0; d < 2; ++d) if ((point[d] < -1.00000000001) || (point[d] > 1.000000000001)) {*inside = PETSC_FALSE; break;} 215 break; 216 default: 217 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 218 } 219 PetscFunctionReturn(0); 220 } 221 222 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 223 { 224 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 225 PetscErrorCode ierr; 226 227 PetscFunctionBegin; 228 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 229 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 230 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 231 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 232 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 233 switch (refiner) { 234 case REFINER_NOOP: 235 break; 236 case REFINER_SIMPLEX_1D: 237 depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */ 238 depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */ 239 break; 240 case REFINER_SIMPLEX_2D: 241 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 242 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 243 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 244 break; 245 case REFINER_HYBRID_SIMPLEX_2D: 246 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 247 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 248 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 249 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 */ 250 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, hybrid cells split into 2 cells */ 251 break; 252 case REFINER_SIMPLEX_TO_HEX_2D: 253 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 254 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 255 depthSize[2] = 3*(cEnd - cStart); /* Every cell split into 3 cells */ 256 break; 257 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 258 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 259 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 260 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 */ 261 depthSize[2] = 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every cell split into 3 cells, hybrid cells split in 4 */ 262 break; 263 case REFINER_HEX_2D: 264 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 265 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 266 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 267 break; 268 case REFINER_HYBRID_HEX_2D: 269 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 270 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 271 /* Quadrilateral */ 272 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 273 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 274 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 275 /* Segment Prisms */ 276 depthSize[0] += 0; /* No hybrid vertices */ 277 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 278 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 279 break; 280 case REFINER_SIMPLEX_3D: 281 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 282 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 */ 283 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 284 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 285 break; 286 case REFINER_HYBRID_SIMPLEX_3D: 287 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 288 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 289 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 290 /* Tetrahedra */ 291 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 292 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 */ 293 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 294 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 295 /* Triangular Prisms */ 296 depthSize[0] += 0; /* No hybrid vertices */ 297 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 298 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 299 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 300 break; 301 case REFINER_SIMPLEX_TO_HEX_3D: 302 depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */ 303 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 */ 304 depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */ 305 depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 306 break; 307 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 308 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 309 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 310 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 311 /* Tetrahedra */ 312 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every interior edge, face and cell */ 313 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 */ 314 depthSize[2] = 3*(fMax - fStart) + 6*(cMax - cStart); /* Every interior face split into 3 faces, 6 faces added for each interior cell */ 315 depthSize[3] = 4*(cMax - cStart); /* Every interior cell split into 8 cells */ 316 /* Triangular Prisms */ 317 depthSize[0] += 0; /* No hybrid vertices */ 318 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and cell */ 319 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 320 depthSize[3] += 3*(cEnd - cMax); /* Every hybrid cell split into 3 cells */ 321 break; 322 case REFINER_HEX_3D: 323 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 324 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 */ 325 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 326 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 327 break; 328 case REFINER_HYBRID_HEX_3D: 329 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 330 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 331 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 332 /* Hexahedra */ 333 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 334 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 */ 335 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 336 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 337 /* Quadrilateral Prisms */ 338 depthSize[0] += 0; /* No hybrid vertices */ 339 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 340 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 341 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 342 break; 343 default: 344 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 345 } 346 PetscFunctionReturn(0); 347 } 348 349 /* Return triangle edge for orientation o, if it is r for o == 0 */ 350 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 351 return (o < 0 ? 2-(o+r) : o+r)%3; 352 } 353 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 354 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 355 } 356 357 /* Return triangle subface for orientation o, if it is r for o == 0 */ 358 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 359 return (o < 0 ? 3-(o+r) : o+r)%3; 360 } 361 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 362 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 363 } 364 365 /* Return the interior edge number connecting the midpoints of the triangle edges r 366 and r+1 in the transitive closure for triangle orientation o */ 367 PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) { 368 return (o < 0 ? 1-(o+r) : o+r)%3; 369 } 370 PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) { 371 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 372 } 373 374 /* Return the interior edge number connecting the midpoint of the triangle edge r 375 (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */ 376 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) { 377 return (o < 0 ? 2-(o+r) : o+r)%3; 378 } 379 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) { 380 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 381 } 382 383 /* Return quad edge for orientation o, if it is r for o == 0 */ 384 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 385 return (o < 0 ? 3-(o+r) : o+r)%4; 386 } 387 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 388 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 389 } 390 391 /* Return quad subface for orientation o, if it is r for o == 0 */ 392 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 393 return (o < 0 ? 4-(o+r) : o+r)%4; 394 } 395 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 396 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 397 } 398 399 static PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd) 400 { 401 IS cIS; 402 PetscErrorCode ierr; 403 404 PetscFunctionBegin; 405 ierr = ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);CHKERRQ(ierr); 406 ierr = DMLabelSetStratumIS(label, value, cIS);CHKERRQ(ierr); 407 ierr = ISDestroy(&cIS);CHKERRQ(ierr); 408 PetscFunctionReturn(0); 409 } 410 411 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 412 { 413 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; 414 DMLabel depthLabel; 415 PetscErrorCode ierr; 416 417 PetscFunctionBegin; 418 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 419 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 420 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 421 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 422 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 423 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 424 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 425 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 426 ierr = DMCreateLabel(rdm,"depth");CHKERRQ(ierr); 427 ierr = DMPlexGetDepthLabel(rdm,&depthLabel);CHKERRQ(ierr); 428 ierr = DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);CHKERRQ(ierr); 429 if (depth > 2) ierr = DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);CHKERRQ(ierr); 430 if (depth > 1) ierr = DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);CHKERRQ(ierr); 431 if (depth > 0) ierr = DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);CHKERRQ(ierr); 432 { 433 DM_Plex *plex = (DM_Plex *) rdm->data; 434 ierr = PetscObjectStateGet((PetscObject) depthLabel, &plex->depthState);CHKERRQ(ierr); 435 } 436 if (!refiner) PetscFunctionReturn(0); 437 switch (refiner) { 438 case REFINER_SIMPLEX_1D: 439 /* All cells have 2 vertices */ 440 for (c = cStart; c < cEnd; ++c) { 441 for (r = 0; r < 2; ++r) { 442 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 443 444 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 445 } 446 } 447 /* Old vertices have identical supports */ 448 for (v = vStart; v < vEnd; ++v) { 449 const PetscInt newp = vStartNew + (v - vStart); 450 PetscInt size; 451 452 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 453 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 454 } 455 /* Cell vertices have support 2 */ 456 for (c = cStart; c < cEnd; ++c) { 457 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 458 459 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 460 } 461 break; 462 case REFINER_SIMPLEX_2D: 463 /* All cells have 3 faces */ 464 for (c = cStart; c < cEnd; ++c) { 465 for (r = 0; r < 4; ++r) { 466 const PetscInt newp = (c - cStart)*4 + r; 467 468 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 469 } 470 } 471 /* Split faces have 2 vertices and the same cells as the parent */ 472 for (f = fStart; f < fEnd; ++f) { 473 for (r = 0; r < 2; ++r) { 474 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 475 PetscInt size; 476 477 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 478 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 479 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 480 } 481 } 482 /* Interior faces have 2 vertices and 2 cells */ 483 for (c = cStart; c < cEnd; ++c) { 484 for (r = 0; r < 3; ++r) { 485 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 486 487 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 488 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 489 } 490 } 491 /* Old vertices have identical supports */ 492 for (v = vStart; v < vEnd; ++v) { 493 const PetscInt newp = vStartNew + (v - vStart); 494 PetscInt size; 495 496 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 497 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 498 } 499 /* Face vertices have 2 + cells*2 supports */ 500 for (f = fStart; f < fEnd; ++f) { 501 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 502 PetscInt size; 503 504 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 505 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 506 } 507 break; 508 case REFINER_SIMPLEX_TO_HEX_2D: 509 /* All cells have 4 faces */ 510 for (c = cStart; c < cEnd; ++c) { 511 for (r = 0; r < 3; ++r) { 512 const PetscInt newp = (c - cStart)*3 + r; 513 514 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 515 } 516 } 517 /* Split faces have 2 vertices and the same cells as the parent */ 518 for (f = fStart; f < fEnd; ++f) { 519 for (r = 0; r < 2; ++r) { 520 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 521 PetscInt size; 522 523 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 524 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 525 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 526 } 527 } 528 /* Interior faces have 2 vertices and 2 cells */ 529 for (c = cStart; c < cEnd; ++c) { 530 for (r = 0; r < 3; ++r) { 531 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 532 533 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 534 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 535 } 536 } 537 /* Old vertices have identical supports */ 538 for (v = vStart; v < vEnd; ++v) { 539 const PetscInt newp = vStartNew + (v - vStart); 540 PetscInt size; 541 542 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 543 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 544 } 545 /* Split-face vertices have cells + 2 supports */ 546 for (f = fStart; f < fEnd; ++f) { 547 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 548 PetscInt size; 549 550 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 551 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 552 } 553 /* Interior vertices have 3 supports */ 554 for (c = cStart; c < cEnd; ++c) { 555 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 556 557 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 558 } 559 break; 560 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 561 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 562 /* the mesh is no longer hybrid */ 563 cMax = PetscMin(cEnd, cMax); 564 /* All cells have 4 faces */ 565 for (c = cStart; c < cMax; ++c) { 566 for (r = 0; r < 3; ++r) { 567 const PetscInt newp = (c - cStart)*3 + r; 568 569 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 570 } 571 } 572 for (c = cMax; c < cEnd; ++c) { 573 for (r = 0; r < 4; ++r) { 574 const PetscInt newp = (cMax - cStart)*3 + (c - cMax)*4 + r; 575 576 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 577 } 578 } 579 /* Split faces have 2 vertices and the same cells as the parent */ 580 for (f = fStart; f < fEnd; ++f) { 581 for (r = 0; r < 2; ++r) { 582 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 583 PetscInt size; 584 585 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 586 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 587 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 588 } 589 } 590 /* Interior faces have 2 vertices and 2 cells */ 591 for (c = cStart; c < cMax; ++c) { 592 for (r = 0; r < 3; ++r) { 593 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 594 595 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 596 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 597 } 598 } 599 /* Hybrid interior faces have 2 vertices and 2 cells */ 600 for (c = cMax; c < cEnd; ++c) { 601 for (r = 0; r < 4; ++r) { 602 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 603 604 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 605 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 606 } 607 } 608 /* Old vertices have identical supports */ 609 for (v = vStart; v < vEnd; ++v) { 610 const PetscInt newp = vStartNew + (v - vStart); 611 PetscInt size; 612 613 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 614 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 615 } 616 /* Split-face vertices have cells + 2 supports */ 617 for (f = fStart; f < fEnd; ++f) { 618 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 619 PetscInt size; 620 621 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 622 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 623 } 624 /* Interior vertices have 3 supports */ 625 for (c = cStart; c < cMax; ++c) { 626 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 627 628 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 629 } 630 /* Hybrid interior vertices have 4 supports */ 631 for (c = cMax; c < cEnd; ++c) { 632 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 633 634 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 635 } 636 break; 637 case REFINER_HEX_2D: 638 /* All cells have 4 faces */ 639 for (c = cStart; c < cEnd; ++c) { 640 for (r = 0; r < 4; ++r) { 641 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 642 643 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 644 } 645 } 646 /* Split faces have 2 vertices and the same cells as the parent */ 647 for (f = fStart; f < fEnd; ++f) { 648 for (r = 0; r < 2; ++r) { 649 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 650 PetscInt size; 651 652 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 653 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 654 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 655 } 656 } 657 /* Interior faces have 2 vertices and 2 cells */ 658 for (c = cStart; c < cEnd; ++c) { 659 for (r = 0; r < 4; ++r) { 660 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 661 662 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 663 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 664 } 665 } 666 /* Old vertices have identical supports */ 667 for (v = vStart; v < vEnd; ++v) { 668 const PetscInt newp = vStartNew + (v - vStart); 669 PetscInt size; 670 671 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 672 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 673 } 674 /* Face vertices have 2 + cells supports */ 675 for (f = fStart; f < fEnd; ++f) { 676 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 677 PetscInt size; 678 679 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 680 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 681 } 682 /* Cell vertices have 4 supports */ 683 for (c = cStart; c < cEnd; ++c) { 684 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 685 686 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 687 } 688 break; 689 case REFINER_HYBRID_SIMPLEX_2D: 690 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 691 cMax = PetscMin(cEnd, cMax); 692 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 693 fMax = PetscMin(fEnd, fMax); 694 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 695 /* Interior cells have 3 faces */ 696 for (c = cStart; c < cMax; ++c) { 697 for (r = 0; r < 4; ++r) { 698 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 699 700 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 701 } 702 } 703 /* Hybrid cells have 4 faces */ 704 for (c = cMax; c < cEnd; ++c) { 705 for (r = 0; r < 2; ++r) { 706 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 707 708 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 709 } 710 } 711 /* Interior split faces have 2 vertices and the same cells as the parent */ 712 for (f = fStart; f < fMax; ++f) { 713 for (r = 0; r < 2; ++r) { 714 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 715 PetscInt size; 716 717 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 718 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 719 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 720 } 721 } 722 /* Interior cell faces have 2 vertices and 2 cells */ 723 for (c = cStart; c < cMax; ++c) { 724 for (r = 0; r < 3; ++r) { 725 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 726 727 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 728 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 729 } 730 } 731 /* Hybrid faces have 2 vertices and the same cells */ 732 for (f = fMax; f < fEnd; ++f) { 733 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 734 PetscInt size; 735 736 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 737 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 738 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 739 } 740 /* Hybrid cell faces have 2 vertices and 2 cells */ 741 for (c = cMax; c < cEnd; ++c) { 742 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 743 744 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 745 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 746 } 747 /* Old vertices have identical supports */ 748 for (v = vStart; v < vEnd; ++v) { 749 const PetscInt newp = vStartNew + (v - vStart); 750 PetscInt size; 751 752 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 753 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 754 } 755 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 756 for (f = fStart; f < fMax; ++f) { 757 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 758 const PetscInt *support; 759 PetscInt size, newSize = 2, s; 760 761 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 762 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 763 for (s = 0; s < size; ++s) { 764 if (support[s] >= cMax) newSize += 1; 765 else newSize += 2; 766 } 767 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 768 } 769 break; 770 case REFINER_HYBRID_HEX_2D: 771 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 772 cMax = PetscMin(cEnd, cMax); 773 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 774 fMax = PetscMin(fEnd, fMax); 775 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 776 /* Interior cells have 4 faces */ 777 for (c = cStart; c < cMax; ++c) { 778 for (r = 0; r < 4; ++r) { 779 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 780 781 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 782 } 783 } 784 /* Hybrid cells have 4 faces */ 785 for (c = cMax; c < cEnd; ++c) { 786 for (r = 0; r < 2; ++r) { 787 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 788 789 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 790 } 791 } 792 /* Interior split faces have 2 vertices and the same cells as the parent */ 793 for (f = fStart; f < fMax; ++f) { 794 for (r = 0; r < 2; ++r) { 795 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 796 PetscInt size; 797 798 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 799 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 800 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 801 } 802 } 803 /* Interior cell faces have 2 vertices and 2 cells */ 804 for (c = cStart; c < cMax; ++c) { 805 for (r = 0; r < 4; ++r) { 806 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 807 808 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 809 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 810 } 811 } 812 /* Hybrid faces have 2 vertices and the same cells */ 813 for (f = fMax; f < fEnd; ++f) { 814 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 815 PetscInt size; 816 817 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 818 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 819 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 820 } 821 /* Hybrid cell faces have 2 vertices and 2 cells */ 822 for (c = cMax; c < cEnd; ++c) { 823 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 824 825 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 826 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 827 } 828 /* Old vertices have identical supports */ 829 for (v = vStart; v < vEnd; ++v) { 830 const PetscInt newp = vStartNew + (v - vStart); 831 PetscInt size; 832 833 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 834 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 835 } 836 /* Face vertices have 2 + cells supports */ 837 for (f = fStart; f < fMax; ++f) { 838 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 839 PetscInt size; 840 841 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 842 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 843 } 844 /* Cell vertices have 4 supports */ 845 for (c = cStart; c < cMax; ++c) { 846 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 847 848 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 849 } 850 break; 851 case REFINER_SIMPLEX_3D: 852 /* All cells have 4 faces */ 853 for (c = cStart; c < cEnd; ++c) { 854 for (r = 0; r < 8; ++r) { 855 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 856 857 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 858 } 859 } 860 /* Split faces have 3 edges and the same cells as the parent */ 861 for (f = fStart; f < fEnd; ++f) { 862 for (r = 0; r < 4; ++r) { 863 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 864 PetscInt size; 865 866 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 867 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 868 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 869 } 870 } 871 /* Interior cell faces have 3 edges and 2 cells */ 872 for (c = cStart; c < cEnd; ++c) { 873 for (r = 0; r < 8; ++r) { 874 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 875 876 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 877 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 878 } 879 } 880 /* Split edges have 2 vertices and the same faces */ 881 for (e = eStart; e < eEnd; ++e) { 882 for (r = 0; r < 2; ++r) { 883 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 884 PetscInt size; 885 886 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 887 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 888 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 889 } 890 } 891 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 892 for (f = fStart; f < fEnd; ++f) { 893 for (r = 0; r < 3; ++r) { 894 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 895 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 896 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 897 898 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 899 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 900 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 901 for (s = 0; s < supportSize; ++s) { 902 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 903 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 904 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 905 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 906 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 907 er = GetTriMidEdgeInverse_Static(ornt[c], r); 908 if (er == eint[c]) { 909 intFaces += 1; 910 } else { 911 intFaces += 2; 912 } 913 } 914 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 915 } 916 } 917 /* Interior cell edges have 2 vertices and 4 faces */ 918 for (c = cStart; c < cEnd; ++c) { 919 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 920 921 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 922 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 923 } 924 /* Old vertices have identical supports */ 925 for (v = vStart; v < vEnd; ++v) { 926 const PetscInt newp = vStartNew + (v - vStart); 927 PetscInt size; 928 929 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 930 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 931 } 932 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 933 for (e = eStart; e < eEnd; ++e) { 934 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 935 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 936 937 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 938 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 939 for (s = 0; s < starSize*2; s += 2) { 940 const PetscInt *cone, *ornt; 941 PetscInt e01, e23; 942 943 if ((star[s] >= cStart) && (star[s] < cEnd)) { 944 /* Check edge 0-1 */ 945 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 946 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 947 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 948 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 949 /* Check edge 2-3 */ 950 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 951 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 952 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 953 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 954 if ((e01 == e) || (e23 == e)) ++cellSize; 955 } 956 } 957 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 958 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 959 } 960 break; 961 case REFINER_HYBRID_SIMPLEX_3D: 962 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 963 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 964 /* Interior cells have 4 faces */ 965 for (c = cStart; c < cMax; ++c) { 966 for (r = 0; r < 8; ++r) { 967 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 968 969 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 970 } 971 } 972 /* Hybrid cells have 5 faces */ 973 for (c = cMax; c < cEnd; ++c) { 974 for (r = 0; r < 4; ++r) { 975 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 976 977 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 978 } 979 } 980 /* Interior split faces have 3 edges and the same cells as the parent */ 981 for (f = fStart; f < fMax; ++f) { 982 for (r = 0; r < 4; ++r) { 983 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 984 PetscInt size; 985 986 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 987 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 988 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 989 } 990 } 991 /* Interior cell faces have 3 edges and 2 cells */ 992 for (c = cStart; c < cMax; ++c) { 993 for (r = 0; r < 8; ++r) { 994 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 995 996 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 997 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 998 } 999 } 1000 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1001 for (f = fMax; f < fEnd; ++f) { 1002 for (r = 0; r < 2; ++r) { 1003 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 1004 PetscInt size; 1005 1006 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1007 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1008 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1009 } 1010 } 1011 /* Hybrid cells faces have 4 edges and 2 cells */ 1012 for (c = cMax; c < cEnd; ++c) { 1013 for (r = 0; r < 3; ++r) { 1014 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1015 1016 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1017 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1018 } 1019 } 1020 /* Interior split edges have 2 vertices and the same faces */ 1021 for (e = eStart; e < eMax; ++e) { 1022 for (r = 0; r < 2; ++r) { 1023 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1024 PetscInt size; 1025 1026 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1027 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1028 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1029 } 1030 } 1031 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 1032 for (f = fStart; f < fMax; ++f) { 1033 for (r = 0; r < 3; ++r) { 1034 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1035 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 1036 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 1037 1038 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1039 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1040 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1041 for (s = 0; s < supportSize; ++s) { 1042 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1043 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1044 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1045 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 1046 if (support[s] < cMax) { 1047 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 1048 er = GetTriMidEdgeInverse_Static(ornt[c], r); 1049 if (er == eint[c]) { 1050 intFaces += 1; 1051 } else { 1052 intFaces += 2; 1053 } 1054 } else { 1055 intFaces += 1; 1056 } 1057 } 1058 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 1059 } 1060 } 1061 /* Interior cell edges have 2 vertices and 4 faces */ 1062 for (c = cStart; c < cMax; ++c) { 1063 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 1064 1065 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1066 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1067 } 1068 /* Hybrid edges have 2 vertices and the same faces */ 1069 for (e = eMax; e < eEnd; ++e) { 1070 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 1071 PetscInt size; 1072 1073 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1074 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1075 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1076 } 1077 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 1078 for (f = fMax; f < fEnd; ++f) { 1079 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 1080 PetscInt size; 1081 1082 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1083 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1084 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 1085 } 1086 /* Interior vertices have identical supports */ 1087 for (v = vStart; v < vEnd; ++v) { 1088 const PetscInt newp = vStartNew + (v - vStart); 1089 PetscInt size; 1090 1091 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1092 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1093 } 1094 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 1095 for (e = eStart; e < eMax; ++e) { 1096 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1097 const PetscInt *support; 1098 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 1099 1100 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1101 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1102 for (s = 0; s < size; ++s) { 1103 if (support[s] < fMax) faceSize += 2; 1104 else faceSize += 1; 1105 } 1106 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1107 for (s = 0; s < starSize*2; s += 2) { 1108 const PetscInt *cone, *ornt; 1109 PetscInt e01, e23; 1110 1111 if ((star[s] >= cStart) && (star[s] < cMax)) { 1112 /* Check edge 0-1 */ 1113 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1114 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1115 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1116 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 1117 /* Check edge 2-3 */ 1118 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1119 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1120 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 1121 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 1122 if ((e01 == e) || (e23 == e)) ++cellSize; 1123 } 1124 } 1125 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1126 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 1127 } 1128 break; 1129 case REFINER_SIMPLEX_TO_HEX_3D: 1130 /* All cells have 6 faces */ 1131 for (c = cStart; c < cEnd; ++c) { 1132 for (r = 0; r < 4; ++r) { 1133 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1134 1135 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1136 } 1137 } 1138 /* Split faces have 4 edges and the same cells as the parent */ 1139 for (f = fStart; f < fEnd; ++f) { 1140 for (r = 0; r < 3; ++r) { 1141 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1142 PetscInt size; 1143 1144 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1145 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1146 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1147 } 1148 } 1149 /* Interior cell faces have 4 edges and 2 cells */ 1150 for (c = cStart; c < cEnd; ++c) { 1151 for (r = 0; r < 6; ++r) { 1152 const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r; 1153 1154 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1155 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1156 } 1157 } 1158 /* Split edges have 2 vertices and the same faces */ 1159 for (e = eStart; e < eEnd; ++e) { 1160 for (r = 0; r < 2; ++r) { 1161 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1162 PetscInt size; 1163 1164 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1165 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1166 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1167 } 1168 } 1169 /* Face edges have 2 vertices and 2 + cell faces supports */ 1170 for (f = fStart; f < fEnd; ++f) { 1171 for (r = 0; r < 3; ++r) { 1172 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1173 PetscInt size; 1174 1175 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1176 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1177 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1178 } 1179 } 1180 /* Interior cell edges have 2 vertices and 3 faces */ 1181 for (c = cStart; c < cEnd; ++c) { 1182 for (r = 0; r < 4; ++r) { 1183 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 1184 1185 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1186 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1187 } 1188 } 1189 /* Old vertices have identical supports */ 1190 for (v = vStart; v < vEnd; ++v) { 1191 const PetscInt newp = vStartNew + (v - vStart); 1192 PetscInt size; 1193 1194 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1195 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1196 } 1197 /* Edge vertices have 2 + faces supports */ 1198 for (e = eStart; e < eEnd; ++e) { 1199 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1200 PetscInt size; 1201 1202 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1203 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1204 } 1205 /* Face vertices have 3 + cells supports */ 1206 for (f = fStart; f < fEnd; ++f) { 1207 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 1208 PetscInt size; 1209 1210 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1211 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1212 } 1213 /* Interior cell vertices have 4 supports */ 1214 for (c = cStart; c < cEnd; ++c) { 1215 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart; 1216 1217 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1218 } 1219 break; 1220 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 1221 /* the mesh is no longer hybrid */ 1222 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1223 cMax = PetscMin(cEnd, cMax); 1224 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1225 fMax = PetscMin(fEnd, fMax); 1226 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 1227 eMax = PetscMin(eEnd, eMax); 1228 /* All cells have 6 faces */ 1229 for (c = cStart; c < cMax; ++c) { 1230 for (r = 0; r < 4; ++r) { 1231 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1232 1233 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1234 } 1235 } 1236 for (c = cMax; c < cEnd; ++c) { 1237 for (r = 0; r < 3; ++r) { 1238 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + r; 1239 1240 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1241 } 1242 } 1243 /* Interior split faces have 4 edges and the same cells as the parent */ 1244 for (f = fStart; f < fMax; ++f) { 1245 for (r = 0; r < 3; ++r) { 1246 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1247 PetscInt size; 1248 1249 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1250 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1251 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1252 } 1253 } 1254 /* Interior cell faces have 4 edges and 2 cells */ 1255 for (c = cStart; c < cMax; ++c) { 1256 for (r = 0; r < 6; ++r) { 1257 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + r; 1258 1259 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1260 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1261 } 1262 } 1263 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1264 for (f = fMax; f < fEnd; ++f) { 1265 for (r = 0; r < 2; ++r) { 1266 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2 + r; 1267 PetscInt size; 1268 1269 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1270 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1271 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1272 } 1273 } 1274 /* Hybrid cell faces have 4 edges and 2 cells */ 1275 for (c = cMax; c < cEnd; ++c) { 1276 for (r = 0; r < 3; ++r) { 1277 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1278 1279 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1280 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1281 } 1282 } 1283 /* Interior split edges have 2 vertices and the same faces */ 1284 for (e = eStart; e < eMax; ++e) { 1285 for (r = 0; r < 2; ++r) { 1286 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1287 PetscInt size; 1288 1289 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1290 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1291 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1292 } 1293 } 1294 /* Interior face edges have 2 vertices and 2 + cell faces supports */ 1295 for (f = fStart; f < fMax; ++f) { 1296 for (r = 0; r < 3; ++r) { 1297 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1298 PetscInt size; 1299 1300 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1301 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1302 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1303 } 1304 } 1305 /* Interior cell edges have 2 vertices and 3 faces */ 1306 for (c = cStart; c < cMax; ++c) { 1307 for (r = 0; r < 4; ++r) { 1308 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 1309 1310 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1311 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1312 } 1313 } 1314 /* Hybrid edges have 2 vertices and the same faces */ 1315 for (e = eMax; e < eEnd; ++e) { 1316 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 1317 PetscInt size; 1318 1319 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1320 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1321 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1322 } 1323 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1324 for (f = fMax; f < fEnd; ++f) { 1325 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 1326 PetscInt size; 1327 1328 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1329 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1330 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1331 } 1332 /* Hybrid cell edges have 2 vertices and 3 faces */ 1333 for (c = cMax; c < cEnd; ++c) { 1334 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1335 1336 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1337 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1338 } 1339 /* Old vertices have identical supports */ 1340 for (v = vStart; v < vEnd; ++v) { 1341 const PetscInt newp = vStartNew + (v - vStart); 1342 PetscInt size; 1343 1344 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1345 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1346 } 1347 /* Interior edge vertices have 2 + faces supports */ 1348 for (e = eStart; e < eMax; ++e) { 1349 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1350 PetscInt size; 1351 1352 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1353 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1354 } 1355 /* Interior face vertices have 3 + cells supports */ 1356 for (f = fStart; f < fMax; ++f) { 1357 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 1358 PetscInt size; 1359 1360 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1361 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1362 } 1363 /* Interior cell vertices have 4 supports */ 1364 for (c = cStart; c < cMax; ++c) { 1365 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 1366 1367 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1368 } 1369 break; 1370 case REFINER_HEX_3D: 1371 /* All cells have 6 faces */ 1372 for (c = cStart; c < cEnd; ++c) { 1373 for (r = 0; r < 8; ++r) { 1374 const PetscInt newp = (c - cStart)*8 + r; 1375 1376 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1377 } 1378 } 1379 /* Split faces have 4 edges and the same cells as the parent */ 1380 for (f = fStart; f < fEnd; ++f) { 1381 for (r = 0; r < 4; ++r) { 1382 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1383 PetscInt size; 1384 1385 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1386 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1387 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1388 } 1389 } 1390 /* Interior faces have 4 edges and 2 cells */ 1391 for (c = cStart; c < cEnd; ++c) { 1392 for (r = 0; r < 12; ++r) { 1393 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 1394 1395 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1396 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1397 } 1398 } 1399 /* Split edges have 2 vertices and the same faces as the parent */ 1400 for (e = eStart; e < eEnd; ++e) { 1401 for (r = 0; r < 2; ++r) { 1402 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1403 PetscInt size; 1404 1405 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1406 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1407 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1408 } 1409 } 1410 /* Face edges have 2 vertices and 2+cells faces */ 1411 for (f = fStart; f < fEnd; ++f) { 1412 for (r = 0; r < 4; ++r) { 1413 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 1414 PetscInt size; 1415 1416 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1417 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1418 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1419 } 1420 } 1421 /* Cell edges have 2 vertices and 4 faces */ 1422 for (c = cStart; c < cEnd; ++c) { 1423 for (r = 0; r < 6; ++r) { 1424 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 1425 1426 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1427 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1428 } 1429 } 1430 /* Old vertices have identical supports */ 1431 for (v = vStart; v < vEnd; ++v) { 1432 const PetscInt newp = vStartNew + (v - vStart); 1433 PetscInt size; 1434 1435 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1436 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1437 } 1438 /* Edge vertices have 2 + faces supports */ 1439 for (e = eStart; e < eEnd; ++e) { 1440 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1441 PetscInt size; 1442 1443 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1444 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1445 } 1446 /* Face vertices have 4 + cells supports */ 1447 for (f = fStart; f < fEnd; ++f) { 1448 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 1449 PetscInt size; 1450 1451 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1452 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1453 } 1454 /* Cell vertices have 6 supports */ 1455 for (c = cStart; c < cEnd; ++c) { 1456 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 1457 1458 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1459 } 1460 break; 1461 case REFINER_HYBRID_HEX_3D: 1462 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 1463 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1464 /* Interior cells have 6 faces */ 1465 for (c = cStart; c < cMax; ++c) { 1466 for (r = 0; r < 8; ++r) { 1467 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1468 1469 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1470 } 1471 } 1472 /* Hybrid cells have 6 faces */ 1473 for (c = cMax; c < cEnd; ++c) { 1474 for (r = 0; r < 4; ++r) { 1475 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1476 1477 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1478 } 1479 } 1480 /* Interior split faces have 4 edges and the same cells as the parent */ 1481 for (f = fStart; f < fMax; ++f) { 1482 for (r = 0; r < 4; ++r) { 1483 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1484 PetscInt size; 1485 1486 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1487 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1488 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1489 } 1490 } 1491 /* Interior cell faces have 4 edges and 2 cells */ 1492 for (c = cStart; c < cMax; ++c) { 1493 for (r = 0; r < 12; ++r) { 1494 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 1495 1496 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1497 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1498 } 1499 } 1500 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1501 for (f = fMax; f < fEnd; ++f) { 1502 for (r = 0; r < 2; ++r) { 1503 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1504 PetscInt size; 1505 1506 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1507 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1508 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1509 } 1510 } 1511 /* Hybrid cells faces have 4 edges and 2 cells */ 1512 for (c = cMax; c < cEnd; ++c) { 1513 for (r = 0; r < 4; ++r) { 1514 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1515 1516 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1517 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1518 } 1519 } 1520 /* Interior split edges have 2 vertices and the same faces as the parent */ 1521 for (e = eStart; e < eMax; ++e) { 1522 for (r = 0; r < 2; ++r) { 1523 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1524 PetscInt size; 1525 1526 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1527 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1528 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1529 } 1530 } 1531 /* Interior face edges have 2 vertices and 2+cells faces */ 1532 for (f = fStart; f < fMax; ++f) { 1533 for (r = 0; r < 4; ++r) { 1534 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1535 PetscInt size; 1536 1537 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1538 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1539 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1540 } 1541 } 1542 /* Interior cell edges have 2 vertices and 4 faces */ 1543 for (c = cStart; c < cMax; ++c) { 1544 for (r = 0; r < 6; ++r) { 1545 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1546 1547 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1548 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1549 } 1550 } 1551 /* Hybrid edges have 2 vertices and the same faces */ 1552 for (e = eMax; e < eEnd; ++e) { 1553 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1554 PetscInt size; 1555 1556 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1557 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1558 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1559 } 1560 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1561 for (f = fMax; f < fEnd; ++f) { 1562 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1563 PetscInt size; 1564 1565 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1566 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1567 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1568 } 1569 /* Hybrid cell edges have 2 vertices and 4 faces */ 1570 for (c = cMax; c < cEnd; ++c) { 1571 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1572 1573 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1574 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1575 } 1576 /* Interior vertices have identical supports */ 1577 for (v = vStart; v < vEnd; ++v) { 1578 const PetscInt newp = vStartNew + (v - vStart); 1579 PetscInt size; 1580 1581 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1582 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1583 } 1584 /* Interior edge vertices have 2 + faces supports */ 1585 for (e = eStart; e < eMax; ++e) { 1586 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1587 PetscInt size; 1588 1589 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1590 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1591 } 1592 /* Interior face vertices have 4 + cells supports */ 1593 for (f = fStart; f < fMax; ++f) { 1594 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1595 PetscInt size; 1596 1597 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1598 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1599 } 1600 /* Interior cell vertices have 6 supports */ 1601 for (c = cStart; c < cMax; ++c) { 1602 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1603 1604 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1605 } 1606 break; 1607 default: 1608 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 1609 } 1610 PetscFunctionReturn(0); 1611 } 1612 1613 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1614 { 1615 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1616 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1617 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1618 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r; 1619 #if defined(PETSC_USE_DEBUG) 1620 PetscInt p; 1621 #endif 1622 PetscErrorCode ierr; 1623 1624 PetscFunctionBegin; 1625 if (!refiner) PetscFunctionReturn(0); 1626 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1627 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1628 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1629 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1630 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1631 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1632 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1633 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1634 switch (refiner) { 1635 case REFINER_SIMPLEX_1D: 1636 /* Max support size of refined mesh is 2 */ 1637 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1638 /* All cells have 2 vertices */ 1639 for (c = cStart; c < cEnd; ++c) { 1640 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1641 1642 for (r = 0; r < 2; ++r) { 1643 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1644 const PetscInt *cone; 1645 PetscInt coneNew[2]; 1646 1647 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1648 coneNew[0] = vStartNew + (cone[0] - vStart); 1649 coneNew[1] = vStartNew + (cone[1] - vStart); 1650 coneNew[(r+1)%2] = newv; 1651 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1652 #if defined(PETSC_USE_DEBUG) 1653 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp, cStartNew, cEndNew); 1654 for (p = 0; p < 2; ++p) { 1655 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); 1656 } 1657 #endif 1658 } 1659 } 1660 /* Old vertices have identical supports */ 1661 for (v = vStart; v < vEnd; ++v) { 1662 const PetscInt newp = vStartNew + (v - vStart); 1663 const PetscInt *support, *cone; 1664 PetscInt size, s; 1665 1666 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1667 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1668 for (s = 0; s < size; ++s) { 1669 PetscInt r = 0; 1670 1671 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1672 if (cone[1] == v) r = 1; 1673 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1674 } 1675 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1676 #if defined(PETSC_USE_DEBUG) 1677 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1678 for (p = 0; p < size; ++p) { 1679 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); 1680 } 1681 #endif 1682 } 1683 /* Cell vertices have support of 2 cells */ 1684 for (c = cStart; c < cEnd; ++c) { 1685 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1686 1687 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1688 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1689 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1690 #if defined(PETSC_USE_DEBUG) 1691 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1692 for (p = 0; p < 2; ++p) { 1693 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); 1694 } 1695 #endif 1696 } 1697 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1698 break; 1699 case REFINER_SIMPLEX_2D: 1700 /* 1701 2 1702 |\ 1703 | \ 1704 | \ 1705 | \ 1706 | C \ 1707 | \ 1708 | \ 1709 2---1---1 1710 |\ D / \ 1711 | 2 0 \ 1712 |A \ / B \ 1713 0---0-------1 1714 */ 1715 /* All cells have 3 faces */ 1716 for (c = cStart; c < cEnd; ++c) { 1717 const PetscInt newp = cStartNew + (c - cStart)*4; 1718 const PetscInt *cone, *ornt; 1719 PetscInt coneNew[3], orntNew[3]; 1720 1721 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1722 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1723 /* A triangle */ 1724 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1725 orntNew[0] = ornt[0]; 1726 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1727 orntNew[1] = -2; 1728 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1729 orntNew[2] = ornt[2]; 1730 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1731 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1732 #if defined(PETSC_USE_DEBUG) 1733 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); 1734 for (p = 0; p < 3; ++p) { 1735 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); 1736 } 1737 #endif 1738 /* B triangle */ 1739 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1740 orntNew[0] = ornt[0]; 1741 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1742 orntNew[1] = ornt[1]; 1743 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1744 orntNew[2] = -2; 1745 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1746 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1747 #if defined(PETSC_USE_DEBUG) 1748 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); 1749 for (p = 0; p < 3; ++p) { 1750 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); 1751 } 1752 #endif 1753 /* C triangle */ 1754 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1755 orntNew[0] = -2; 1756 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1757 orntNew[1] = ornt[1]; 1758 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1759 orntNew[2] = ornt[2]; 1760 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1761 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1762 #if defined(PETSC_USE_DEBUG) 1763 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); 1764 for (p = 0; p < 3; ++p) { 1765 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); 1766 } 1767 #endif 1768 /* D triangle */ 1769 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1770 orntNew[0] = 0; 1771 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1772 orntNew[1] = 0; 1773 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1774 orntNew[2] = 0; 1775 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1776 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1777 #if defined(PETSC_USE_DEBUG) 1778 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); 1779 for (p = 0; p < 3; ++p) { 1780 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); 1781 } 1782 #endif 1783 } 1784 /* Split faces have 2 vertices and the same cells as the parent */ 1785 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1786 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1787 for (f = fStart; f < fEnd; ++f) { 1788 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1789 1790 for (r = 0; r < 2; ++r) { 1791 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1792 const PetscInt *cone, *ornt, *support; 1793 PetscInt coneNew[2], coneSize, c, supportSize, s; 1794 1795 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1796 coneNew[0] = vStartNew + (cone[0] - vStart); 1797 coneNew[1] = vStartNew + (cone[1] - vStart); 1798 coneNew[(r+1)%2] = newv; 1799 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1800 #if defined(PETSC_USE_DEBUG) 1801 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1802 for (p = 0; p < 2; ++p) { 1803 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); 1804 } 1805 #endif 1806 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1807 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1808 for (s = 0; s < supportSize; ++s) { 1809 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1810 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1811 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1812 for (c = 0; c < coneSize; ++c) { 1813 if (cone[c] == f) break; 1814 } 1815 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1816 } 1817 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1818 #if defined(PETSC_USE_DEBUG) 1819 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1820 for (p = 0; p < supportSize; ++p) { 1821 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); 1822 } 1823 #endif 1824 } 1825 } 1826 /* Interior faces have 2 vertices and 2 cells */ 1827 for (c = cStart; c < cEnd; ++c) { 1828 const PetscInt *cone; 1829 1830 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1831 for (r = 0; r < 3; ++r) { 1832 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1833 PetscInt coneNew[2]; 1834 PetscInt supportNew[2]; 1835 1836 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1837 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1838 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1839 #if defined(PETSC_USE_DEBUG) 1840 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1841 for (p = 0; p < 2; ++p) { 1842 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); 1843 } 1844 #endif 1845 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1846 supportNew[1] = (c - cStart)*4 + 3; 1847 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1848 #if defined(PETSC_USE_DEBUG) 1849 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1850 for (p = 0; p < 2; ++p) { 1851 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); 1852 } 1853 #endif 1854 } 1855 } 1856 /* Old vertices have identical supports */ 1857 for (v = vStart; v < vEnd; ++v) { 1858 const PetscInt newp = vStartNew + (v - vStart); 1859 const PetscInt *support, *cone; 1860 PetscInt size, s; 1861 1862 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1863 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1864 for (s = 0; s < size; ++s) { 1865 PetscInt r = 0; 1866 1867 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1868 if (cone[1] == v) r = 1; 1869 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1870 } 1871 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1872 #if defined(PETSC_USE_DEBUG) 1873 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1874 for (p = 0; p < size; ++p) { 1875 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); 1876 } 1877 #endif 1878 } 1879 /* Face vertices have 2 + cells*2 supports */ 1880 for (f = fStart; f < fEnd; ++f) { 1881 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1882 const PetscInt *cone, *support; 1883 PetscInt size, s; 1884 1885 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1886 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1887 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1888 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1889 for (s = 0; s < size; ++s) { 1890 PetscInt r = 0; 1891 1892 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1893 if (cone[1] == f) r = 1; 1894 else if (cone[2] == f) r = 2; 1895 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1896 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1897 } 1898 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1899 #if defined(PETSC_USE_DEBUG) 1900 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1901 for (p = 0; p < 2+size*2; ++p) { 1902 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); 1903 } 1904 #endif 1905 } 1906 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1907 break; 1908 case REFINER_SIMPLEX_TO_HEX_2D: 1909 /* 1910 2 1911 |\ 1912 | \ 1913 | \ 1914 | \ 1915 | C \ 1916 | \ 1917 2 1 1918 |\ / \ 1919 | 2 1 \ 1920 | \/ \ 1921 | | \ 1922 |A | B \ 1923 | 0 \ 1924 | | \ 1925 0---0----------1 1926 */ 1927 /* All cells have 4 faces */ 1928 for (c = cStart; c < cEnd; ++c) { 1929 const PetscInt newp = cStartNew + (c - cStart)*3; 1930 const PetscInt *cone, *ornt; 1931 PetscInt coneNew[4], orntNew[4]; 1932 1933 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1934 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1935 /* A quad */ 1936 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1937 orntNew[0] = ornt[0]; 1938 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1939 orntNew[1] = 0; 1940 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1941 orntNew[2] = -2; 1942 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1943 orntNew[3] = ornt[2]; 1944 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1945 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1946 #if defined(PETSC_USE_DEBUG) 1947 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); 1948 for (p = 0; p < 4; ++p) { 1949 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); 1950 } 1951 #endif 1952 /* B quad */ 1953 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1954 orntNew[0] = ornt[0]; 1955 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1956 orntNew[1] = ornt[1]; 1957 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1958 orntNew[2] = 0; 1959 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1960 orntNew[3] = -2; 1961 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1962 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1963 #if defined(PETSC_USE_DEBUG) 1964 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); 1965 for (p = 0; p < 4; ++p) { 1966 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); 1967 } 1968 #endif 1969 /* C quad */ 1970 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1971 orntNew[0] = ornt[1]; 1972 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1973 orntNew[1] = ornt[2]; 1974 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1975 orntNew[2] = 0; 1976 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1977 orntNew[3] = -2; 1978 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1979 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1980 #if defined(PETSC_USE_DEBUG) 1981 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); 1982 for (p = 0; p < 4; ++p) { 1983 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); 1984 } 1985 #endif 1986 } 1987 /* Split faces have 2 vertices and the same cells as the parent */ 1988 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1989 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1990 for (f = fStart; f < fEnd; ++f) { 1991 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1992 1993 for (r = 0; r < 2; ++r) { 1994 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1995 const PetscInt *cone, *ornt, *support; 1996 PetscInt coneNew[2], coneSize, c, supportSize, s; 1997 1998 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1999 coneNew[0] = vStartNew + (cone[0] - vStart); 2000 coneNew[1] = vStartNew + (cone[1] - vStart); 2001 coneNew[(r+1)%2] = newv; 2002 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2003 #if defined(PETSC_USE_DEBUG) 2004 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2005 for (p = 0; p < 2; ++p) { 2006 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); 2007 } 2008 #endif 2009 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2010 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2011 for (s = 0; s < supportSize; ++s) { 2012 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2013 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2014 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2015 for (c = 0; c < coneSize; ++c) { 2016 if (cone[c] == f) break; 2017 } 2018 supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2019 } 2020 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2021 #if defined(PETSC_USE_DEBUG) 2022 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2023 for (p = 0; p < supportSize; ++p) { 2024 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); 2025 } 2026 #endif 2027 } 2028 } 2029 /* Interior faces have 2 vertices and 2 cells */ 2030 for (c = cStart; c < cEnd; ++c) { 2031 const PetscInt *cone; 2032 2033 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2034 for (r = 0; r < 3; ++r) { 2035 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2036 PetscInt coneNew[2]; 2037 PetscInt supportNew[2]; 2038 2039 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2040 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2041 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2042 #if defined(PETSC_USE_DEBUG) 2043 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2044 for (p = 0; p < 2; ++p) { 2045 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); 2046 } 2047 #endif 2048 supportNew[0] = (c - cStart)*3 + r%3; 2049 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2050 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2051 #if defined(PETSC_USE_DEBUG) 2052 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2053 for (p = 0; p < 2; ++p) { 2054 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); 2055 } 2056 #endif 2057 } 2058 } 2059 /* Old vertices have identical supports */ 2060 for (v = vStart; v < vEnd; ++v) { 2061 const PetscInt newp = vStartNew + (v - vStart); 2062 const PetscInt *support, *cone; 2063 PetscInt size, s; 2064 2065 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2066 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2067 for (s = 0; s < size; ++s) { 2068 PetscInt r = 0; 2069 2070 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2071 if (cone[1] == v) r = 1; 2072 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2073 } 2074 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2075 #if defined(PETSC_USE_DEBUG) 2076 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2077 for (p = 0; p < size; ++p) { 2078 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); 2079 } 2080 #endif 2081 } 2082 /* Split-face vertices have cells + 2 supports */ 2083 for (f = fStart; f < fEnd; ++f) { 2084 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2085 const PetscInt *cone, *support; 2086 PetscInt size, s; 2087 2088 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2089 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2090 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2091 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2092 for (s = 0; s < size; ++s) { 2093 PetscInt r = 0; 2094 2095 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2096 if (cone[1] == f) r = 1; 2097 else if (cone[2] == f) r = 2; 2098 supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2099 } 2100 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2101 #if defined(PETSC_USE_DEBUG) 2102 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2103 for (p = 0; p < 2+size; ++p) { 2104 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); 2105 } 2106 #endif 2107 } 2108 /* Interior vertices have 3 supports */ 2109 for (c = cStart; c < cEnd; ++c) { 2110 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2111 2112 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2113 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2114 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2115 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2116 } 2117 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2118 break; 2119 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 2120 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2121 cMax = PetscMin(cEnd, cMax); 2122 for (c = cStart; c < cMax; ++c) { 2123 const PetscInt newp = cStartNew + (c - cStart)*3; 2124 const PetscInt *cone, *ornt; 2125 PetscInt coneNew[4], orntNew[4]; 2126 2127 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2128 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2129 /* A quad */ 2130 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2131 orntNew[0] = ornt[0]; 2132 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2133 orntNew[1] = 0; 2134 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2135 orntNew[2] = -2; 2136 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2137 orntNew[3] = ornt[2]; 2138 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2139 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2140 #if defined(PETSC_USE_DEBUG) 2141 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); 2142 for (p = 0; p < 4; ++p) { 2143 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); 2144 } 2145 #endif 2146 /* B quad */ 2147 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2148 orntNew[0] = ornt[0]; 2149 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2150 orntNew[1] = ornt[1]; 2151 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2152 orntNew[2] = 0; 2153 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2154 orntNew[3] = -2; 2155 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2156 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2157 #if defined(PETSC_USE_DEBUG) 2158 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); 2159 for (p = 0; p < 4; ++p) { 2160 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); 2161 } 2162 #endif 2163 /* C quad */ 2164 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2165 orntNew[0] = ornt[1]; 2166 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2167 orntNew[1] = ornt[2]; 2168 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2169 orntNew[2] = 0; 2170 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2171 orntNew[3] = -2; 2172 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2173 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2174 #if defined(PETSC_USE_DEBUG) 2175 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); 2176 for (p = 0; p < 4; ++p) { 2177 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); 2178 } 2179 #endif 2180 } 2181 /* 2182 2---------1---------3 2183 | | | 2184 | D 1 C | 2185 | | | 2186 2----2----0----3----3 2187 | | | 2188 | A 0 B | 2189 | | | 2190 0---------0---------1 2191 */ 2192 /* Parent cells are input as prisms but children are quads, since the mesh is no longer hybrid */ 2193 for (c = cMax; c < cEnd; ++c) { 2194 const PetscInt newp = cStartNew + (cMax - cStart)*3 + (c - cMax)*4; 2195 const PetscInt newpt = (cMax - cStart)*3 + (c - cMax)*4; 2196 const PetscInt *cone, *ornt; 2197 PetscInt coneNew[4], orntNew[4]; 2198 2199 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2200 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2201 /* A quad */ 2202 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2203 orntNew[0] = ornt[0]; 2204 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2205 orntNew[1] = 0; 2206 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2207 orntNew[2] = -2; 2208 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2209 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2210 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2211 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2212 #if defined(PETSC_USE_DEBUG) 2213 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); 2214 for (p = 0; p < 4; ++p) { 2215 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); 2216 } 2217 #endif 2218 /* B quad */ 2219 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2220 orntNew[0] = ornt[0]; 2221 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2222 orntNew[1] = ornt[3]; 2223 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2224 orntNew[2] = 0; 2225 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2226 orntNew[3] = -2; 2227 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2228 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2229 #if defined(PETSC_USE_DEBUG) 2230 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); 2231 for (p = 0; p < 4; ++p) { 2232 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); 2233 } 2234 #endif 2235 /* C quad */ 2236 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2237 orntNew[0] = -2; 2238 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2239 orntNew[1] = ornt[3]; 2240 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2241 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2242 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2243 orntNew[3] = 0; 2244 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2245 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2246 #if defined(PETSC_USE_DEBUG) 2247 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); 2248 for (p = 0; p < 4; ++p) { 2249 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); 2250 } 2251 #endif 2252 /* D quad */ 2253 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2254 orntNew[0] = 0; 2255 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2256 orntNew[1] = -2; 2257 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2258 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2259 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2260 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2261 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2262 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2263 #if defined(PETSC_USE_DEBUG) 2264 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); 2265 for (p = 0; p < 4; ++p) { 2266 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2267 } 2268 #endif 2269 } 2270 /* Split faces have 2 vertices and the same cells as the parent */ 2271 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2272 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2273 for (f = fStart; f < fEnd; ++f) { 2274 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2275 2276 for (r = 0; r < 2; ++r) { 2277 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2278 const PetscInt *cone, *ornt, *support; 2279 PetscInt coneNew[2], coneSize, c, supportSize, s; 2280 2281 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2282 coneNew[0] = vStartNew + (cone[0] - vStart); 2283 coneNew[1] = vStartNew + (cone[1] - vStart); 2284 coneNew[(r+1)%2] = newv; 2285 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2286 #if defined(PETSC_USE_DEBUG) 2287 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2288 for (p = 0; p < 2; ++p) { 2289 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); 2290 } 2291 #endif 2292 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2293 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2294 for (s = 0; s < supportSize; ++s) { 2295 const PetscInt p2q[4][2] = { {0, 1}, 2296 {3, 2}, 2297 {0, 3}, 2298 {1, 2} }; 2299 2300 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2301 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2302 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2303 for (c = 0; c < coneSize; ++c) { 2304 if (cone[c] == f) break; 2305 } 2306 if (coneSize == 3) supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2307 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]); 2308 else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2309 } 2310 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2311 #if defined(PETSC_USE_DEBUG) 2312 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2313 for (p = 0; p < supportSize; ++p) { 2314 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); 2315 } 2316 #endif 2317 } 2318 } 2319 /* Interior faces have 2 vertices and 2 cells */ 2320 for (c = cStart; c < cMax; ++c) { 2321 const PetscInt *cone; 2322 2323 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2324 for (r = 0; r < 3; ++r) { 2325 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2326 PetscInt coneNew[2]; 2327 PetscInt supportNew[2]; 2328 2329 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2330 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2331 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2332 #if defined(PETSC_USE_DEBUG) 2333 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2334 for (p = 0; p < 2; ++p) { 2335 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); 2336 } 2337 #endif 2338 supportNew[0] = (c - cStart)*3 + r%3; 2339 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2340 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2341 #if defined(PETSC_USE_DEBUG) 2342 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2343 for (p = 0; p < 2; ++p) { 2344 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); 2345 } 2346 #endif 2347 } 2348 } 2349 /* Hybrid interior faces have 2 vertices and 2 cells */ 2350 for (c = cMax; c < cEnd; ++c) { 2351 const PetscInt *cone; 2352 PetscInt coneNew[2], supportNew[2]; 2353 2354 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2355 for (r = 0; r < 4; ++r) { 2356 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 2357 2358 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2359 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (cMax - cStart) + (c - cMax); 2360 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2361 #if defined(PETSC_USE_DEBUG) 2362 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2363 for (p = 0; p < 2; ++p) { 2364 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); 2365 } 2366 #endif 2367 if (r==0) { 2368 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2369 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2370 } else if (r==1) { 2371 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2372 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2373 } else if (r==2) { 2374 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2375 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2376 } else { 2377 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2378 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2379 } 2380 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2381 #if defined(PETSC_USE_DEBUG) 2382 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2383 for (p = 0; p < 2; ++p) { 2384 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); 2385 } 2386 #endif 2387 } 2388 } 2389 /* Old vertices have identical supports */ 2390 for (v = vStart; v < vEnd; ++v) { 2391 const PetscInt newp = vStartNew + (v - vStart); 2392 const PetscInt *support, *cone; 2393 PetscInt size, s; 2394 2395 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2396 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2397 for (s = 0; s < size; ++s) { 2398 PetscInt r = 0; 2399 2400 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2401 if (cone[1] == v) r = 1; 2402 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2403 } 2404 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2405 #if defined(PETSC_USE_DEBUG) 2406 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2407 for (p = 0; p < size; ++p) { 2408 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); 2409 } 2410 #endif 2411 } 2412 /* Split-face vertices have cells + 2 supports */ 2413 for (f = fStart; f < fEnd; ++f) { 2414 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2415 const PetscInt *cone, *support; 2416 PetscInt size, s; 2417 2418 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2419 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2420 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2421 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2422 for (s = 0; s < size; ++s) { 2423 PetscInt r = 0, coneSize; 2424 2425 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2426 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2427 if (coneSize == 3) { 2428 if (cone[1] == f) r = 1; 2429 else if (cone[2] == f) r = 2; 2430 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2431 } else if (coneSize == 4) { 2432 if (cone[1] == f) r = 1; 2433 else if (cone[2] == f) r = 2; 2434 else if (cone[3] == f) r = 3; 2435 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (support[s] - cMax)*4 + r; 2436 } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2437 } 2438 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2439 #if defined(PETSC_USE_DEBUG) 2440 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2441 for (p = 0; p < 2+size; ++p) { 2442 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); 2443 } 2444 #endif 2445 } 2446 /* Interior vertices have 3 supports */ 2447 for (c = cStart; c < cMax; ++c) { 2448 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2449 2450 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2451 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2452 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2453 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2454 } 2455 /* Hybrid interior vertices have 4 supports */ 2456 for (c = cMax; c < cEnd; ++c) { 2457 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2458 2459 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 0; 2460 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 1; 2461 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 2; 2462 supportRef[3] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 3; 2463 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2464 } 2465 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2466 break; 2467 case REFINER_HEX_2D: 2468 /* 2469 3---------2---------2 2470 | | | 2471 | D 2 C | 2472 | | | 2473 3----3----0----1----1 2474 | | | 2475 | A 0 B | 2476 | | | 2477 0---------0---------1 2478 */ 2479 /* All cells have 4 faces */ 2480 for (c = cStart; c < cEnd; ++c) { 2481 const PetscInt newp = (c - cStart)*4; 2482 const PetscInt *cone, *ornt; 2483 PetscInt coneNew[4], orntNew[4]; 2484 2485 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2486 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2487 /* A quad */ 2488 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2489 orntNew[0] = ornt[0]; 2490 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2491 orntNew[1] = 0; 2492 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2493 orntNew[2] = -2; 2494 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2495 orntNew[3] = ornt[3]; 2496 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2497 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2498 #if defined(PETSC_USE_DEBUG) 2499 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); 2500 for (p = 0; p < 4; ++p) { 2501 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); 2502 } 2503 #endif 2504 /* B quad */ 2505 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2506 orntNew[0] = ornt[0]; 2507 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2508 orntNew[1] = ornt[1]; 2509 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2510 orntNew[2] = -2; 2511 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2512 orntNew[3] = -2; 2513 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2514 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2515 #if defined(PETSC_USE_DEBUG) 2516 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); 2517 for (p = 0; p < 4; ++p) { 2518 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); 2519 } 2520 #endif 2521 /* C quad */ 2522 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2523 orntNew[0] = 0; 2524 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2525 orntNew[1] = ornt[1]; 2526 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2527 orntNew[2] = ornt[2]; 2528 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2529 orntNew[3] = -2; 2530 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2531 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2532 #if defined(PETSC_USE_DEBUG) 2533 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); 2534 for (p = 0; p < 4; ++p) { 2535 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); 2536 } 2537 #endif 2538 /* D quad */ 2539 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2540 orntNew[0] = 0; 2541 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2542 orntNew[1] = 0; 2543 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2544 orntNew[2] = ornt[2]; 2545 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2546 orntNew[3] = ornt[3]; 2547 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2548 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2549 #if defined(PETSC_USE_DEBUG) 2550 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); 2551 for (p = 0; p < 4; ++p) { 2552 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); 2553 } 2554 #endif 2555 } 2556 /* Split faces have 2 vertices and the same cells as the parent */ 2557 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2558 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2559 for (f = fStart; f < fEnd; ++f) { 2560 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2561 2562 for (r = 0; r < 2; ++r) { 2563 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2564 const PetscInt *cone, *ornt, *support; 2565 PetscInt coneNew[2], coneSize, c, supportSize, s; 2566 2567 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2568 coneNew[0] = vStartNew + (cone[0] - vStart); 2569 coneNew[1] = vStartNew + (cone[1] - vStart); 2570 coneNew[(r+1)%2] = newv; 2571 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2572 #if defined(PETSC_USE_DEBUG) 2573 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2574 for (p = 0; p < 2; ++p) { 2575 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); 2576 } 2577 #endif 2578 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2579 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2580 for (s = 0; s < supportSize; ++s) { 2581 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2582 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2583 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2584 for (c = 0; c < coneSize; ++c) { 2585 if (cone[c] == f) break; 2586 } 2587 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2588 } 2589 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2590 #if defined(PETSC_USE_DEBUG) 2591 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2592 for (p = 0; p < supportSize; ++p) { 2593 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); 2594 } 2595 #endif 2596 } 2597 } 2598 /* Interior faces have 2 vertices and 2 cells */ 2599 for (c = cStart; c < cEnd; ++c) { 2600 const PetscInt *cone; 2601 PetscInt coneNew[2], supportNew[2]; 2602 2603 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2604 for (r = 0; r < 4; ++r) { 2605 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2606 2607 if (r==1 || r==2) { 2608 coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2609 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2610 } else { 2611 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2612 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2613 } 2614 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2615 #if defined(PETSC_USE_DEBUG) 2616 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2617 for (p = 0; p < 2; ++p) { 2618 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); 2619 } 2620 #endif 2621 supportNew[0] = (c - cStart)*4 + r; 2622 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2623 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2624 #if defined(PETSC_USE_DEBUG) 2625 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2626 for (p = 0; p < 2; ++p) { 2627 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); 2628 } 2629 #endif 2630 } 2631 } 2632 /* Old vertices have identical supports */ 2633 for (v = vStart; v < vEnd; ++v) { 2634 const PetscInt newp = vStartNew + (v - vStart); 2635 const PetscInt *support, *cone; 2636 PetscInt size, s; 2637 2638 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2639 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2640 for (s = 0; s < size; ++s) { 2641 PetscInt r = 0; 2642 2643 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2644 if (cone[1] == v) r = 1; 2645 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2646 } 2647 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2648 #if defined(PETSC_USE_DEBUG) 2649 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2650 for (p = 0; p < size; ++p) { 2651 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); 2652 } 2653 #endif 2654 } 2655 /* Face vertices have 2 + cells supports */ 2656 for (f = fStart; f < fEnd; ++f) { 2657 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2658 const PetscInt *cone, *support; 2659 PetscInt size, s; 2660 2661 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2662 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2663 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2664 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2665 for (s = 0; s < size; ++s) { 2666 PetscInt r = 0; 2667 2668 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2669 if (cone[1] == f) r = 1; 2670 else if (cone[2] == f) r = 2; 2671 else if (cone[3] == f) r = 3; 2672 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 2673 } 2674 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2675 #if defined(PETSC_USE_DEBUG) 2676 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2677 for (p = 0; p < 2+size; ++p) { 2678 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); 2679 } 2680 #endif 2681 } 2682 /* Cell vertices have 4 supports */ 2683 for (c = cStart; c < cEnd; ++c) { 2684 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2685 PetscInt supportNew[4]; 2686 2687 for (r = 0; r < 4; ++r) { 2688 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2689 } 2690 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2691 } 2692 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2693 break; 2694 case REFINER_HYBRID_SIMPLEX_2D: 2695 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2696 cMax = PetscMin(cEnd, cMax); 2697 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2698 fMax = PetscMin(fEnd, fMax); 2699 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2700 /* Interior cells have 3 faces */ 2701 for (c = cStart; c < cMax; ++c) { 2702 const PetscInt newp = cStartNew + (c - cStart)*4; 2703 const PetscInt *cone, *ornt; 2704 PetscInt coneNew[3], orntNew[3]; 2705 2706 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2707 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2708 /* A triangle */ 2709 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2710 orntNew[0] = ornt[0]; 2711 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2712 orntNew[1] = -2; 2713 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2714 orntNew[2] = ornt[2]; 2715 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2716 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2717 #if defined(PETSC_USE_DEBUG) 2718 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); 2719 for (p = 0; p < 3; ++p) { 2720 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); 2721 } 2722 #endif 2723 /* B triangle */ 2724 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2725 orntNew[0] = ornt[0]; 2726 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2727 orntNew[1] = ornt[1]; 2728 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2729 orntNew[2] = -2; 2730 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2731 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2732 #if defined(PETSC_USE_DEBUG) 2733 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); 2734 for (p = 0; p < 3; ++p) { 2735 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); 2736 } 2737 #endif 2738 /* C triangle */ 2739 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2740 orntNew[0] = -2; 2741 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2742 orntNew[1] = ornt[1]; 2743 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2744 orntNew[2] = ornt[2]; 2745 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2746 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2747 #if defined(PETSC_USE_DEBUG) 2748 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); 2749 for (p = 0; p < 3; ++p) { 2750 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); 2751 } 2752 #endif 2753 /* D triangle */ 2754 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2755 orntNew[0] = 0; 2756 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2757 orntNew[1] = 0; 2758 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2759 orntNew[2] = 0; 2760 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2761 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2762 #if defined(PETSC_USE_DEBUG) 2763 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); 2764 for (p = 0; p < 3; ++p) { 2765 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); 2766 } 2767 #endif 2768 } 2769 /* 2770 2----3----3 2771 | | 2772 | B | 2773 | | 2774 0----4--- 1 2775 | | 2776 | A | 2777 | | 2778 0----2----1 2779 */ 2780 /* Hybrid cells have 4 faces */ 2781 for (c = cMax; c < cEnd; ++c) { 2782 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2783 const PetscInt *cone, *ornt; 2784 PetscInt coneNew[4], orntNew[4], r; 2785 2786 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2787 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2788 r = (ornt[0] < 0 ? 1 : 0); 2789 /* A quad */ 2790 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2791 orntNew[0] = ornt[0]; 2792 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2793 orntNew[1] = ornt[1]; 2794 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2795 orntNew[2+r] = 0; 2796 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2797 orntNew[3-r] = 0; 2798 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2799 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2800 #if defined(PETSC_USE_DEBUG) 2801 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); 2802 for (p = 0; p < 4; ++p) { 2803 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); 2804 } 2805 #endif 2806 /* B quad */ 2807 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2808 orntNew[0] = ornt[0]; 2809 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2810 orntNew[1] = ornt[1]; 2811 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2812 orntNew[2+r] = 0; 2813 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2814 orntNew[3-r] = 0; 2815 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2816 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2817 #if defined(PETSC_USE_DEBUG) 2818 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); 2819 for (p = 0; p < 4; ++p) { 2820 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); 2821 } 2822 #endif 2823 } 2824 /* Interior split faces have 2 vertices and the same cells as the parent */ 2825 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2826 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2827 for (f = fStart; f < fMax; ++f) { 2828 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2829 2830 for (r = 0; r < 2; ++r) { 2831 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2832 const PetscInt *cone, *ornt, *support; 2833 PetscInt coneNew[2], coneSize, c, supportSize, s; 2834 2835 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2836 coneNew[0] = vStartNew + (cone[0] - vStart); 2837 coneNew[1] = vStartNew + (cone[1] - vStart); 2838 coneNew[(r+1)%2] = newv; 2839 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2840 #if defined(PETSC_USE_DEBUG) 2841 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2842 for (p = 0; p < 2; ++p) { 2843 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); 2844 } 2845 #endif 2846 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2847 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2848 for (s = 0; s < supportSize; ++s) { 2849 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2850 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2851 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2852 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2853 if (support[s] >= cMax) { 2854 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2855 } else { 2856 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2857 } 2858 } 2859 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2860 #if defined(PETSC_USE_DEBUG) 2861 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2862 for (p = 0; p < supportSize; ++p) { 2863 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); 2864 } 2865 #endif 2866 } 2867 } 2868 /* Interior cell faces have 2 vertices and 2 cells */ 2869 for (c = cStart; c < cMax; ++c) { 2870 const PetscInt *cone; 2871 2872 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2873 for (r = 0; r < 3; ++r) { 2874 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 2875 PetscInt coneNew[2]; 2876 PetscInt supportNew[2]; 2877 2878 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2879 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 2880 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2881 #if defined(PETSC_USE_DEBUG) 2882 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2883 for (p = 0; p < 2; ++p) { 2884 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); 2885 } 2886 #endif 2887 supportNew[0] = (c - cStart)*4 + (r+1)%3; 2888 supportNew[1] = (c - cStart)*4 + 3; 2889 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2890 #if defined(PETSC_USE_DEBUG) 2891 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2892 for (p = 0; p < 2; ++p) { 2893 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); 2894 } 2895 #endif 2896 } 2897 } 2898 /* Interior hybrid faces have 2 vertices and the same cells */ 2899 for (f = fMax; f < fEnd; ++f) { 2900 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 2901 const PetscInt *cone, *ornt; 2902 const PetscInt *support; 2903 PetscInt coneNew[2]; 2904 PetscInt supportNew[2]; 2905 PetscInt size, s, r; 2906 2907 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2908 coneNew[0] = vStartNew + (cone[0] - vStart); 2909 coneNew[1] = vStartNew + (cone[1] - vStart); 2910 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2911 #if defined(PETSC_USE_DEBUG) 2912 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2913 for (p = 0; p < 2; ++p) { 2914 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); 2915 } 2916 #endif 2917 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2918 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2919 for (s = 0; s < size; ++s) { 2920 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2921 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2922 for (r = 0; r < 2; ++r) { 2923 if (cone[r+2] == f) break; 2924 } 2925 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 2926 } 2927 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2928 #if defined(PETSC_USE_DEBUG) 2929 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2930 for (p = 0; p < size; ++p) { 2931 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); 2932 } 2933 #endif 2934 } 2935 /* Cell hybrid faces have 2 vertices and 2 cells */ 2936 for (c = cMax; c < cEnd; ++c) { 2937 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2938 const PetscInt *cone; 2939 PetscInt coneNew[2]; 2940 PetscInt supportNew[2]; 2941 2942 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2943 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2944 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2945 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2946 #if defined(PETSC_USE_DEBUG) 2947 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2948 for (p = 0; p < 2; ++p) { 2949 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); 2950 } 2951 #endif 2952 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2953 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2954 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2955 #if defined(PETSC_USE_DEBUG) 2956 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2957 for (p = 0; p < 2; ++p) { 2958 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); 2959 } 2960 #endif 2961 } 2962 /* Old vertices have identical supports */ 2963 for (v = vStart; v < vEnd; ++v) { 2964 const PetscInt newp = vStartNew + (v - vStart); 2965 const PetscInt *support, *cone; 2966 PetscInt size, s; 2967 2968 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2969 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2970 for (s = 0; s < size; ++s) { 2971 if (support[s] >= fMax) { 2972 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 2973 } else { 2974 PetscInt r = 0; 2975 2976 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2977 if (cone[1] == v) r = 1; 2978 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2979 } 2980 } 2981 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2982 #if defined(PETSC_USE_DEBUG) 2983 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2984 for (p = 0; p < size; ++p) { 2985 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); 2986 } 2987 #endif 2988 } 2989 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 2990 for (f = fStart; f < fMax; ++f) { 2991 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2992 const PetscInt *cone, *support; 2993 PetscInt size, newSize = 2, s; 2994 2995 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2996 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2997 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2998 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2999 for (s = 0; s < size; ++s) { 3000 PetscInt r = 0; 3001 3002 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3003 if (support[s] >= cMax) { 3004 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 3005 3006 newSize += 1; 3007 } else { 3008 if (cone[1] == f) r = 1; 3009 else if (cone[2] == f) r = 2; 3010 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 3011 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 3012 3013 newSize += 2; 3014 } 3015 } 3016 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3017 #if defined(PETSC_USE_DEBUG) 3018 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3019 for (p = 0; p < newSize; ++p) { 3020 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); 3021 } 3022 #endif 3023 } 3024 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3025 break; 3026 case REFINER_HYBRID_HEX_2D: 3027 /* Hybrid Hex 2D */ 3028 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 3029 cMax = PetscMin(cEnd, cMax); 3030 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 3031 fMax = PetscMin(fEnd, fMax); 3032 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 3033 /* Interior cells have 4 faces */ 3034 for (c = cStart; c < cMax; ++c) { 3035 const PetscInt newp = cStartNew + (c - cStart)*4; 3036 const PetscInt *cone, *ornt; 3037 PetscInt coneNew[4], orntNew[4]; 3038 3039 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3040 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3041 /* A quad */ 3042 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3043 orntNew[0] = ornt[0]; 3044 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3045 orntNew[1] = 0; 3046 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3047 orntNew[2] = -2; 3048 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 3049 orntNew[3] = ornt[3]; 3050 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3051 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3052 #if defined(PETSC_USE_DEBUG) 3053 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); 3054 for (p = 0; p < 4; ++p) { 3055 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); 3056 } 3057 #endif 3058 /* B quad */ 3059 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3060 orntNew[0] = ornt[0]; 3061 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3062 orntNew[1] = ornt[1]; 3063 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3064 orntNew[2] = 0; 3065 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3066 orntNew[3] = -2; 3067 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3068 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3069 #if defined(PETSC_USE_DEBUG) 3070 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); 3071 for (p = 0; p < 4; ++p) { 3072 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); 3073 } 3074 #endif 3075 /* C quad */ 3076 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3077 orntNew[0] = -2; 3078 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3079 orntNew[1] = ornt[1]; 3080 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 3081 orntNew[2] = ornt[2]; 3082 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3083 orntNew[3] = 0; 3084 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3085 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3086 #if defined(PETSC_USE_DEBUG) 3087 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); 3088 for (p = 0; p < 4; ++p) { 3089 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); 3090 } 3091 #endif 3092 /* D quad */ 3093 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3094 orntNew[0] = 0; 3095 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3096 orntNew[1] = -2; 3097 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 3098 orntNew[2] = ornt[2]; 3099 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 3100 orntNew[3] = ornt[3]; 3101 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3102 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3103 #if defined(PETSC_USE_DEBUG) 3104 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); 3105 for (p = 0; p < 4; ++p) { 3106 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); 3107 } 3108 #endif 3109 } 3110 /* 3111 2----3----3 3112 | | 3113 | B | 3114 | | 3115 0----4--- 1 3116 | | 3117 | A | 3118 | | 3119 0----2----1 3120 */ 3121 /* Hybrid cells have 4 faces */ 3122 for (c = cMax; c < cEnd; ++c) { 3123 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 3124 const PetscInt *cone, *ornt; 3125 PetscInt coneNew[4], orntNew[4]; 3126 3127 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3128 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3129 /* A quad */ 3130 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3131 orntNew[0] = ornt[0]; 3132 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3133 orntNew[1] = ornt[1]; 3134 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 3135 orntNew[2] = 0; 3136 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3137 orntNew[3] = 0; 3138 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3139 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3140 #if defined(PETSC_USE_DEBUG) 3141 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); 3142 for (p = 0; p < 4; ++p) { 3143 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); 3144 } 3145 #endif 3146 /* B quad */ 3147 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3148 orntNew[0] = ornt[0]; 3149 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3150 orntNew[1] = ornt[1]; 3151 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3152 orntNew[2] = 0; 3153 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 3154 orntNew[3] = 0; 3155 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3156 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3157 #if defined(PETSC_USE_DEBUG) 3158 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); 3159 for (p = 0; p < 4; ++p) { 3160 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); 3161 } 3162 #endif 3163 } 3164 /* Interior split faces have 2 vertices and the same cells as the parent */ 3165 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3166 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3167 for (f = fStart; f < fMax; ++f) { 3168 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 3169 3170 for (r = 0; r < 2; ++r) { 3171 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 3172 const PetscInt *cone, *ornt, *support; 3173 PetscInt coneNew[2], coneSize, c, supportSize, s; 3174 3175 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3176 coneNew[0] = vStartNew + (cone[0] - vStart); 3177 coneNew[1] = vStartNew + (cone[1] - vStart); 3178 coneNew[(r+1)%2] = newv; 3179 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3180 #if defined(PETSC_USE_DEBUG) 3181 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3182 for (p = 0; p < 2; ++p) { 3183 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); 3184 } 3185 #endif 3186 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3187 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3188 for (s = 0; s < supportSize; ++s) { 3189 if (support[s] >= cMax) { 3190 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3191 } else { 3192 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3193 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3194 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3195 for (c = 0; c < coneSize; ++c) { 3196 if (cone[c] == f) break; 3197 } 3198 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3199 } 3200 } 3201 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3202 #if defined(PETSC_USE_DEBUG) 3203 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3204 for (p = 0; p < supportSize; ++p) { 3205 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); 3206 } 3207 #endif 3208 } 3209 } 3210 /* Interior cell faces have 2 vertices and 2 cells */ 3211 for (c = cStart; c < cMax; ++c) { 3212 const PetscInt *cone; 3213 3214 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3215 for (r = 0; r < 4; ++r) { 3216 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3217 PetscInt coneNew[2], supportNew[2]; 3218 3219 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 3220 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3221 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3222 #if defined(PETSC_USE_DEBUG) 3223 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3224 for (p = 0; p < 2; ++p) { 3225 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); 3226 } 3227 #endif 3228 supportNew[0] = (c - cStart)*4 + r; 3229 supportNew[1] = (c - cStart)*4 + (r+1)%4; 3230 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3231 #if defined(PETSC_USE_DEBUG) 3232 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3233 for (p = 0; p < 2; ++p) { 3234 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); 3235 } 3236 #endif 3237 } 3238 } 3239 /* Hybrid faces have 2 vertices and the same cells */ 3240 for (f = fMax; f < fEnd; ++f) { 3241 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 3242 const PetscInt *cone, *support; 3243 PetscInt coneNew[2], supportNew[2]; 3244 PetscInt size, s, r; 3245 3246 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3247 coneNew[0] = vStartNew + (cone[0] - vStart); 3248 coneNew[1] = vStartNew + (cone[1] - vStart); 3249 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3250 #if defined(PETSC_USE_DEBUG) 3251 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3252 for (p = 0; p < 2; ++p) { 3253 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); 3254 } 3255 #endif 3256 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3257 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3258 for (s = 0; s < size; ++s) { 3259 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3260 for (r = 0; r < 2; ++r) { 3261 if (cone[r+2] == f) break; 3262 } 3263 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3264 } 3265 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3266 #if defined(PETSC_USE_DEBUG) 3267 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3268 for (p = 0; p < size; ++p) { 3269 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); 3270 } 3271 #endif 3272 } 3273 /* Cell hybrid faces have 2 vertices and 2 cells */ 3274 for (c = cMax; c < cEnd; ++c) { 3275 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3276 const PetscInt *cone; 3277 PetscInt coneNew[2], supportNew[2]; 3278 3279 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3280 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3281 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3282 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3283 #if defined(PETSC_USE_DEBUG) 3284 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3285 for (p = 0; p < 2; ++p) { 3286 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); 3287 } 3288 #endif 3289 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3290 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3291 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3292 #if defined(PETSC_USE_DEBUG) 3293 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3294 for (p = 0; p < 2; ++p) { 3295 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); 3296 } 3297 #endif 3298 } 3299 /* Old vertices have identical supports */ 3300 for (v = vStart; v < vEnd; ++v) { 3301 const PetscInt newp = vStartNew + (v - vStart); 3302 const PetscInt *support, *cone; 3303 PetscInt size, s; 3304 3305 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3306 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3307 for (s = 0; s < size; ++s) { 3308 if (support[s] >= fMax) { 3309 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 3310 } else { 3311 PetscInt r = 0; 3312 3313 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3314 if (cone[1] == v) r = 1; 3315 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3316 } 3317 } 3318 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3319 #if defined(PETSC_USE_DEBUG) 3320 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3321 for (p = 0; p < size; ++p) { 3322 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); 3323 } 3324 #endif 3325 } 3326 /* Face vertices have 2 + cells supports */ 3327 for (f = fStart; f < fMax; ++f) { 3328 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3329 const PetscInt *cone, *support; 3330 PetscInt size, s; 3331 3332 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3333 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3334 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3335 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3336 for (s = 0; s < size; ++s) { 3337 PetscInt r = 0; 3338 3339 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3340 if (support[s] >= cMax) { 3341 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 3342 } else { 3343 if (cone[1] == f) r = 1; 3344 else if (cone[2] == f) r = 2; 3345 else if (cone[3] == f) r = 3; 3346 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 3347 } 3348 } 3349 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3350 #if defined(PETSC_USE_DEBUG) 3351 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3352 for (p = 0; p < 2+size; ++p) { 3353 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); 3354 } 3355 #endif 3356 } 3357 /* Cell vertices have 4 supports */ 3358 for (c = cStart; c < cMax; ++c) { 3359 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3360 PetscInt supportNew[4]; 3361 3362 for (r = 0; r < 4; ++r) { 3363 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3364 } 3365 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3366 } 3367 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3368 break; 3369 case REFINER_SIMPLEX_3D: 3370 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3371 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3372 for (c = cStart; c < cEnd; ++c) { 3373 const PetscInt newp = cStartNew + (c - cStart)*8; 3374 const PetscInt *cone, *ornt; 3375 PetscInt coneNew[4], orntNew[4]; 3376 3377 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3378 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3379 /* A tetrahedron: {0, a, c, d} */ 3380 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3381 orntNew[0] = ornt[0]; 3382 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3383 orntNew[1] = ornt[1]; 3384 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3385 orntNew[2] = ornt[2]; 3386 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3387 orntNew[3] = 0; 3388 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3389 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3390 #if defined(PETSC_USE_DEBUG) 3391 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); 3392 for (p = 0; p < 4; ++p) { 3393 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); 3394 } 3395 #endif 3396 /* B tetrahedron: {a, 1, b, e} */ 3397 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3398 orntNew[0] = ornt[0]; 3399 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3400 orntNew[1] = ornt[1]; 3401 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3402 orntNew[2] = 0; 3403 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3404 orntNew[3] = ornt[3]; 3405 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3406 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3407 #if defined(PETSC_USE_DEBUG) 3408 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); 3409 for (p = 0; p < 4; ++p) { 3410 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); 3411 } 3412 #endif 3413 /* C tetrahedron: {c, b, 2, f} */ 3414 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3415 orntNew[0] = ornt[0]; 3416 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3417 orntNew[1] = 0; 3418 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3419 orntNew[2] = ornt[2]; 3420 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3421 orntNew[3] = ornt[3]; 3422 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3423 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3424 #if defined(PETSC_USE_DEBUG) 3425 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); 3426 for (p = 0; p < 4; ++p) { 3427 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); 3428 } 3429 #endif 3430 /* D tetrahedron: {d, e, f, 3} */ 3431 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3432 orntNew[0] = 0; 3433 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3434 orntNew[1] = ornt[1]; 3435 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3436 orntNew[2] = ornt[2]; 3437 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3438 orntNew[3] = ornt[3]; 3439 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3440 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3441 #if defined(PETSC_USE_DEBUG) 3442 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); 3443 for (p = 0; p < 4; ++p) { 3444 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); 3445 } 3446 #endif 3447 /* A' tetrahedron: {c, d, a, f} */ 3448 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3449 orntNew[0] = -3; 3450 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3451 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3452 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3453 orntNew[2] = 0; 3454 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3455 orntNew[3] = 2; 3456 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3457 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3458 #if defined(PETSC_USE_DEBUG) 3459 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); 3460 for (p = 0; p < 4; ++p) { 3461 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); 3462 } 3463 #endif 3464 /* B' tetrahedron: {e, b, a, f} */ 3465 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3466 orntNew[0] = -2; 3467 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 3468 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 3469 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3470 orntNew[2] = 0; 3471 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3472 orntNew[3] = 0; 3473 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3474 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3475 #if defined(PETSC_USE_DEBUG) 3476 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); 3477 for (p = 0; p < 4; ++p) { 3478 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); 3479 } 3480 #endif 3481 /* C' tetrahedron: {f, a, c, b} */ 3482 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3483 orntNew[0] = -2; 3484 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3485 orntNew[1] = -2; 3486 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3487 orntNew[2] = -1; 3488 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 3489 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3490 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3491 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3492 #if defined(PETSC_USE_DEBUG) 3493 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); 3494 for (p = 0; p < 4; ++p) { 3495 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); 3496 } 3497 #endif 3498 /* D' tetrahedron: {f, a, e, d} */ 3499 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3500 orntNew[0] = -2; 3501 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3502 orntNew[1] = -1; 3503 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3504 orntNew[2] = -2; 3505 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 3506 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 3507 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3508 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3509 #if defined(PETSC_USE_DEBUG) 3510 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); 3511 for (p = 0; p < 4; ++p) { 3512 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); 3513 } 3514 #endif 3515 } 3516 /* Split faces have 3 edges and the same cells as the parent */ 3517 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3518 ierr = PetscMalloc1(2 + maxSupportSize*3, &supportRef);CHKERRQ(ierr); 3519 for (f = fStart; f < fEnd; ++f) { 3520 const PetscInt newp = fStartNew + (f - fStart)*4; 3521 const PetscInt *cone, *ornt, *support; 3522 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3523 3524 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3525 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3526 /* A triangle */ 3527 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3528 orntNew[0] = ornt[0]; 3529 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3530 orntNew[1] = -2; 3531 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3532 orntNew[2] = ornt[2]; 3533 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3534 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3535 #if defined(PETSC_USE_DEBUG) 3536 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); 3537 for (p = 0; p < 3; ++p) { 3538 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); 3539 } 3540 #endif 3541 /* B triangle */ 3542 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3543 orntNew[0] = ornt[0]; 3544 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3545 orntNew[1] = ornt[1]; 3546 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3547 orntNew[2] = -2; 3548 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3549 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3550 #if defined(PETSC_USE_DEBUG) 3551 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); 3552 for (p = 0; p < 3; ++p) { 3553 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); 3554 } 3555 #endif 3556 /* C triangle */ 3557 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3558 orntNew[0] = -2; 3559 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3560 orntNew[1] = ornt[1]; 3561 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3562 orntNew[2] = ornt[2]; 3563 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3564 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3565 #if defined(PETSC_USE_DEBUG) 3566 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); 3567 for (p = 0; p < 3; ++p) { 3568 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); 3569 } 3570 #endif 3571 /* D triangle */ 3572 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3573 orntNew[0] = 0; 3574 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3575 orntNew[1] = 0; 3576 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3577 orntNew[2] = 0; 3578 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3579 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3580 #if defined(PETSC_USE_DEBUG) 3581 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); 3582 for (p = 0; p < 3; ++p) { 3583 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); 3584 } 3585 #endif 3586 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3587 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3588 for (r = 0; r < 4; ++r) { 3589 for (s = 0; s < supportSize; ++s) { 3590 PetscInt subf; 3591 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3592 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3593 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3594 for (c = 0; c < coneSize; ++c) { 3595 if (cone[c] == f) break; 3596 } 3597 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3598 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3599 } 3600 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3601 #if defined(PETSC_USE_DEBUG) 3602 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); 3603 for (p = 0; p < supportSize; ++p) { 3604 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); 3605 } 3606 #endif 3607 } 3608 } 3609 /* Interior faces have 3 edges and 2 cells */ 3610 for (c = cStart; c < cEnd; ++c) { 3611 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 3612 const PetscInt *cone, *ornt; 3613 PetscInt coneNew[3], orntNew[3]; 3614 PetscInt supportNew[2]; 3615 3616 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3617 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3618 /* Face A: {c, a, d} */ 3619 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3620 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3621 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3622 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3623 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3624 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3625 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3626 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3627 #if defined(PETSC_USE_DEBUG) 3628 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3629 for (p = 0; p < 3; ++p) { 3630 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); 3631 } 3632 #endif 3633 supportNew[0] = (c - cStart)*8 + 0; 3634 supportNew[1] = (c - cStart)*8 + 0+4; 3635 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3636 #if defined(PETSC_USE_DEBUG) 3637 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3638 for (p = 0; p < 2; ++p) { 3639 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); 3640 } 3641 #endif 3642 ++newp; 3643 /* Face B: {a, b, e} */ 3644 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3645 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3646 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3647 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3648 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3649 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3650 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3651 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3652 #if defined(PETSC_USE_DEBUG) 3653 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3654 for (p = 0; p < 3; ++p) { 3655 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); 3656 } 3657 #endif 3658 supportNew[0] = (c - cStart)*8 + 1; 3659 supportNew[1] = (c - cStart)*8 + 1+4; 3660 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3661 #if defined(PETSC_USE_DEBUG) 3662 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3663 for (p = 0; p < 2; ++p) { 3664 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); 3665 } 3666 #endif 3667 ++newp; 3668 /* Face C: {c, f, b} */ 3669 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3670 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3671 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3672 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3673 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3674 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3675 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3676 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3677 #if defined(PETSC_USE_DEBUG) 3678 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3679 for (p = 0; p < 3; ++p) { 3680 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); 3681 } 3682 #endif 3683 supportNew[0] = (c - cStart)*8 + 2; 3684 supportNew[1] = (c - cStart)*8 + 2+4; 3685 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3686 #if defined(PETSC_USE_DEBUG) 3687 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3688 for (p = 0; p < 2; ++p) { 3689 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); 3690 } 3691 #endif 3692 ++newp; 3693 /* Face D: {d, e, f} */ 3694 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3695 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3696 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3697 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3698 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3699 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3700 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3701 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3702 #if defined(PETSC_USE_DEBUG) 3703 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3704 for (p = 0; p < 3; ++p) { 3705 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); 3706 } 3707 #endif 3708 supportNew[0] = (c - cStart)*8 + 3; 3709 supportNew[1] = (c - cStart)*8 + 3+4; 3710 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3711 #if defined(PETSC_USE_DEBUG) 3712 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3713 for (p = 0; p < 2; ++p) { 3714 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); 3715 } 3716 #endif 3717 ++newp; 3718 /* Face E: {d, f, a} */ 3719 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3720 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3721 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3722 orntNew[1] = -2; 3723 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3724 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3725 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3726 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3727 #if defined(PETSC_USE_DEBUG) 3728 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3729 for (p = 0; p < 3; ++p) { 3730 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); 3731 } 3732 #endif 3733 supportNew[0] = (c - cStart)*8 + 0+4; 3734 supportNew[1] = (c - cStart)*8 + 3+4; 3735 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3736 #if defined(PETSC_USE_DEBUG) 3737 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3738 for (p = 0; p < 2; ++p) { 3739 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); 3740 } 3741 #endif 3742 ++newp; 3743 /* Face F: {c, a, f} */ 3744 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3745 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3746 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3747 orntNew[1] = 0; 3748 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3749 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3750 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3751 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3752 #if defined(PETSC_USE_DEBUG) 3753 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3754 for (p = 0; p < 3; ++p) { 3755 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); 3756 } 3757 #endif 3758 supportNew[0] = (c - cStart)*8 + 0+4; 3759 supportNew[1] = (c - cStart)*8 + 2+4; 3760 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3761 #if defined(PETSC_USE_DEBUG) 3762 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3763 for (p = 0; p < 2; ++p) { 3764 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); 3765 } 3766 #endif 3767 ++newp; 3768 /* Face G: {e, a, f} */ 3769 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3770 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3771 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3772 orntNew[1] = 0; 3773 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3774 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3775 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3776 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3777 #if defined(PETSC_USE_DEBUG) 3778 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3779 for (p = 0; p < 3; ++p) { 3780 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); 3781 } 3782 #endif 3783 supportNew[0] = (c - cStart)*8 + 1+4; 3784 supportNew[1] = (c - cStart)*8 + 3+4; 3785 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3786 #if defined(PETSC_USE_DEBUG) 3787 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3788 for (p = 0; p < 2; ++p) { 3789 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); 3790 } 3791 #endif 3792 ++newp; 3793 /* Face H: {a, b, f} */ 3794 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3795 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3796 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3797 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3798 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3799 orntNew[2] = -2; 3800 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3801 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3802 #if defined(PETSC_USE_DEBUG) 3803 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3804 for (p = 0; p < 3; ++p) { 3805 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); 3806 } 3807 #endif 3808 supportNew[0] = (c - cStart)*8 + 1+4; 3809 supportNew[1] = (c - cStart)*8 + 2+4; 3810 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3811 #if defined(PETSC_USE_DEBUG) 3812 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3813 for (p = 0; p < 2; ++p) { 3814 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); 3815 } 3816 #endif 3817 ++newp; 3818 } 3819 /* Split Edges have 2 vertices and the same faces as the parent */ 3820 for (e = eStart; e < eEnd; ++e) { 3821 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3822 3823 for (r = 0; r < 2; ++r) { 3824 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3825 const PetscInt *cone, *ornt, *support; 3826 PetscInt coneNew[2], coneSize, c, supportSize, s; 3827 3828 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3829 coneNew[0] = vStartNew + (cone[0] - vStart); 3830 coneNew[1] = vStartNew + (cone[1] - vStart); 3831 coneNew[(r+1)%2] = newv; 3832 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3833 #if defined(PETSC_USE_DEBUG) 3834 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3835 for (p = 0; p < 2; ++p) { 3836 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); 3837 } 3838 #endif 3839 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3840 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3841 for (s = 0; s < supportSize; ++s) { 3842 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3843 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3844 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3845 for (c = 0; c < coneSize; ++c) { 3846 if (cone[c] == e) break; 3847 } 3848 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3849 } 3850 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3851 #if defined(PETSC_USE_DEBUG) 3852 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3853 for (p = 0; p < supportSize; ++p) { 3854 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); 3855 } 3856 #endif 3857 } 3858 } 3859 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3860 for (f = fStart; f < fEnd; ++f) { 3861 const PetscInt *cone, *ornt, *support; 3862 PetscInt coneSize, supportSize, s; 3863 3864 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3865 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3866 for (r = 0; r < 3; ++r) { 3867 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3868 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3869 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3870 -1, -1, 1, 6, 0, 4, 3871 2, 5, 3, 4, -1, -1, 3872 -1, -1, 3, 6, 2, 7}; 3873 3874 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3875 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3876 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3877 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3878 #if defined(PETSC_USE_DEBUG) 3879 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3880 for (p = 0; p < 2; ++p) { 3881 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); 3882 } 3883 #endif 3884 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3885 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3886 for (s = 0; s < supportSize; ++s) { 3887 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3888 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3889 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3890 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3891 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3892 er = GetTriMidEdgeInverse_Static(ornt[c], r); 3893 if (er == eint[c]) { 3894 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3895 } else { 3896 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3897 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3898 } 3899 } 3900 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3901 #if defined(PETSC_USE_DEBUG) 3902 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3903 for (p = 0; p < intFaces; ++p) { 3904 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); 3905 } 3906 #endif 3907 } 3908 } 3909 /* Interior edges have 2 vertices and 4 faces */ 3910 for (c = cStart; c < cEnd; ++c) { 3911 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3912 const PetscInt *cone, *ornt, *fcone; 3913 PetscInt coneNew[2], supportNew[4], find; 3914 3915 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3916 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3917 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3918 find = GetTriEdge_Static(ornt[0], 0); 3919 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3920 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3921 find = GetTriEdge_Static(ornt[2], 1); 3922 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3923 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3924 #if defined(PETSC_USE_DEBUG) 3925 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3926 for (p = 0; p < 2; ++p) { 3927 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); 3928 } 3929 #endif 3930 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3931 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3932 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3933 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3934 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3935 #if defined(PETSC_USE_DEBUG) 3936 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3937 for (p = 0; p < 4; ++p) { 3938 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); 3939 } 3940 #endif 3941 } 3942 /* Old vertices have identical supports */ 3943 for (v = vStart; v < vEnd; ++v) { 3944 const PetscInt newp = vStartNew + (v - vStart); 3945 const PetscInt *support, *cone; 3946 PetscInt size, s; 3947 3948 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3949 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3950 for (s = 0; s < size; ++s) { 3951 PetscInt r = 0; 3952 3953 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3954 if (cone[1] == v) r = 1; 3955 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3956 } 3957 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3958 #if defined(PETSC_USE_DEBUG) 3959 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3960 for (p = 0; p < size; ++p) { 3961 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); 3962 } 3963 #endif 3964 } 3965 /* Edge vertices have 2 + face*2 + 0/1 supports */ 3966 for (e = eStart; e < eEnd; ++e) { 3967 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3968 const PetscInt *cone, *support; 3969 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 3970 3971 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3972 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3973 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3974 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3975 for (s = 0; s < size; ++s) { 3976 PetscInt r = 0; 3977 3978 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3979 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3980 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3981 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3982 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3983 } 3984 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3985 for (s = 0; s < starSize*2; s += 2) { 3986 const PetscInt *cone, *ornt; 3987 PetscInt e01, e23; 3988 3989 if ((star[s] >= cStart) && (star[s] < cEnd)) { 3990 /* Check edge 0-1 */ 3991 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3992 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3993 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3994 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3995 /* Check edge 2-3 */ 3996 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3997 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3998 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3999 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4000 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 4001 } 4002 } 4003 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4004 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4005 #if defined(PETSC_USE_DEBUG) 4006 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4007 for (p = 0; p < 2+size*2+cellSize; ++p) { 4008 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); 4009 } 4010 #endif 4011 } 4012 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4013 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4014 break; 4015 case REFINER_HYBRID_SIMPLEX_3D: 4016 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4017 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 4018 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4019 for (c = cStart; c < cMax; ++c) { 4020 const PetscInt newp = cStartNew + (c - cStart)*8; 4021 const PetscInt *cone, *ornt; 4022 PetscInt coneNew[4], orntNew[4]; 4023 4024 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4025 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4026 /* A tetrahedron: {0, a, c, d} */ 4027 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 4028 orntNew[0] = ornt[0]; 4029 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 4030 orntNew[1] = ornt[1]; 4031 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 4032 orntNew[2] = ornt[2]; 4033 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4034 orntNew[3] = 0; 4035 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4036 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4037 #if defined(PETSC_USE_DEBUG) 4038 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); 4039 for (p = 0; p < 4; ++p) { 4040 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); 4041 } 4042 #endif 4043 /* B tetrahedron: {a, 1, b, e} */ 4044 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 4045 orntNew[0] = ornt[0]; 4046 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 4047 orntNew[1] = ornt[1]; 4048 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4049 orntNew[2] = 0; 4050 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 4051 orntNew[3] = ornt[3]; 4052 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4053 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4054 #if defined(PETSC_USE_DEBUG) 4055 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); 4056 for (p = 0; p < 4; ++p) { 4057 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); 4058 } 4059 #endif 4060 /* C tetrahedron: {c, b, 2, f} */ 4061 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 4062 orntNew[0] = ornt[0]; 4063 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4064 orntNew[1] = 0; 4065 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 4066 orntNew[2] = ornt[2]; 4067 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 4068 orntNew[3] = ornt[3]; 4069 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4070 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4071 #if defined(PETSC_USE_DEBUG) 4072 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); 4073 for (p = 0; p < 4; ++p) { 4074 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); 4075 } 4076 #endif 4077 /* D tetrahedron: {d, e, f, 3} */ 4078 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4079 orntNew[0] = 0; 4080 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 4081 orntNew[1] = ornt[1]; 4082 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 4083 orntNew[2] = ornt[2]; 4084 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 4085 orntNew[3] = ornt[3]; 4086 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4087 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4088 #if defined(PETSC_USE_DEBUG) 4089 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); 4090 for (p = 0; p < 4; ++p) { 4091 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); 4092 } 4093 #endif 4094 /* A' tetrahedron: {d, a, c, f} */ 4095 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4096 orntNew[0] = -3; 4097 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 4098 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 4099 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4100 orntNew[2] = 0; 4101 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4102 orntNew[3] = 2; 4103 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4104 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4105 #if defined(PETSC_USE_DEBUG) 4106 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); 4107 for (p = 0; p < 4; ++p) { 4108 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); 4109 } 4110 #endif 4111 /* B' tetrahedron: {e, b, a, f} */ 4112 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4113 orntNew[0] = -3; 4114 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4115 orntNew[1] = 1; 4116 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4117 orntNew[2] = 0; 4118 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 4119 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 4120 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4121 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4122 #if defined(PETSC_USE_DEBUG) 4123 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); 4124 for (p = 0; p < 4; ++p) { 4125 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); 4126 } 4127 #endif 4128 /* C' tetrahedron: {b, f, c, a} */ 4129 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4130 orntNew[0] = -3; 4131 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 4132 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 4133 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4134 orntNew[2] = -3; 4135 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4136 orntNew[3] = -2; 4137 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4138 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4139 #if defined(PETSC_USE_DEBUG) 4140 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); 4141 for (p = 0; p < 4; ++p) { 4142 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); 4143 } 4144 #endif 4145 /* D' tetrahedron: {f, e, d, a} */ 4146 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4147 orntNew[0] = -3; 4148 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4149 orntNew[1] = -3; 4150 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 4151 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 4152 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4153 orntNew[3] = -3; 4154 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4155 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4156 #if defined(PETSC_USE_DEBUG) 4157 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); 4158 for (p = 0; p < 4; ++p) { 4159 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); 4160 } 4161 #endif 4162 } 4163 /* Hybrid cells have 5 faces */ 4164 for (c = cMax; c < cEnd; ++c) { 4165 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 4166 const PetscInt *cone, *ornt, *fornt; 4167 PetscInt coneNew[5], orntNew[5], o, of, i; 4168 4169 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4170 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4171 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4172 o = ornt[0] < 0 ? -1 : 1; 4173 for (r = 0; r < 3; ++r) { 4174 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 4175 orntNew[0] = ornt[0]; 4176 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 4177 orntNew[1] = ornt[1]; 4178 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 4179 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 4180 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 4181 orntNew[i] = 0; 4182 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 4183 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 4184 orntNew[i] = 0; 4185 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 4186 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 4187 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); 4188 orntNew[i] = 0; 4189 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4190 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4191 #if defined(PETSC_USE_DEBUG) 4192 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); 4193 for (p = 0; p < 2; ++p) { 4194 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4195 } 4196 for (p = 2; p < 5; ++p) { 4197 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); 4198 } 4199 #endif 4200 } 4201 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 4202 orntNew[0] = 0; 4203 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 4204 orntNew[1] = 0; 4205 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 4206 orntNew[2] = 0; 4207 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 4208 orntNew[3] = 0; 4209 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 4210 orntNew[4] = 0; 4211 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4212 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4213 #if defined(PETSC_USE_DEBUG) 4214 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); 4215 for (p = 0; p < 2; ++p) { 4216 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); 4217 } 4218 for (p = 2; p < 5; ++p) { 4219 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); 4220 } 4221 #endif 4222 } 4223 /* Split faces have 3 edges and the same cells as the parent */ 4224 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4225 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4226 for (f = fStart; f < fMax; ++f) { 4227 const PetscInt newp = fStartNew + (f - fStart)*4; 4228 const PetscInt *cone, *ornt, *support; 4229 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 4230 4231 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4232 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4233 /* A triangle */ 4234 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4235 orntNew[0] = ornt[0]; 4236 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4237 orntNew[1] = -2; 4238 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4239 orntNew[2] = ornt[2]; 4240 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4241 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4242 #if defined(PETSC_USE_DEBUG) 4243 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); 4244 for (p = 0; p < 3; ++p) { 4245 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); 4246 } 4247 #endif 4248 /* B triangle */ 4249 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4250 orntNew[0] = ornt[0]; 4251 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4252 orntNew[1] = ornt[1]; 4253 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4254 orntNew[2] = -2; 4255 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4256 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4257 #if defined(PETSC_USE_DEBUG) 4258 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); 4259 for (p = 0; p < 3; ++p) { 4260 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); 4261 } 4262 #endif 4263 /* C triangle */ 4264 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4265 orntNew[0] = -2; 4266 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4267 orntNew[1] = ornt[1]; 4268 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4269 orntNew[2] = ornt[2]; 4270 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4271 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4272 #if defined(PETSC_USE_DEBUG) 4273 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); 4274 for (p = 0; p < 3; ++p) { 4275 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); 4276 } 4277 #endif 4278 /* D triangle */ 4279 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4280 orntNew[0] = 0; 4281 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4282 orntNew[1] = 0; 4283 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4284 orntNew[2] = 0; 4285 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4286 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4287 #if defined(PETSC_USE_DEBUG) 4288 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); 4289 for (p = 0; p < 3; ++p) { 4290 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); 4291 } 4292 #endif 4293 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4294 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4295 for (r = 0; r < 4; ++r) { 4296 for (s = 0; s < supportSize; ++s) { 4297 PetscInt subf; 4298 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4299 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4300 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4301 for (c = 0; c < coneSize; ++c) { 4302 if (cone[c] == f) break; 4303 } 4304 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4305 if (support[s] < cMax) { 4306 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 4307 } else { 4308 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 4309 } 4310 } 4311 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4312 #if defined(PETSC_USE_DEBUG) 4313 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); 4314 for (p = 0; p < supportSize; ++p) { 4315 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); 4316 } 4317 #endif 4318 } 4319 } 4320 /* Interior cell faces have 3 edges and 2 cells */ 4321 for (c = cStart; c < cMax; ++c) { 4322 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 4323 const PetscInt *cone, *ornt; 4324 PetscInt coneNew[3], orntNew[3]; 4325 PetscInt supportNew[2]; 4326 4327 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4328 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4329 /* Face A: {c, a, d} */ 4330 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4331 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4332 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4333 orntNew[1] = ornt[1] < 0 ? -2 : 0; 4334 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 4335 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4336 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4337 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4338 #if defined(PETSC_USE_DEBUG) 4339 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4340 for (p = 0; p < 3; ++p) { 4341 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); 4342 } 4343 #endif 4344 supportNew[0] = (c - cStart)*8 + 0; 4345 supportNew[1] = (c - cStart)*8 + 0+4; 4346 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4347 #if defined(PETSC_USE_DEBUG) 4348 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4349 for (p = 0; p < 2; ++p) { 4350 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); 4351 } 4352 #endif 4353 ++newp; 4354 /* Face B: {a, b, e} */ 4355 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4356 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4357 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 4358 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4359 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4360 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4361 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4362 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4363 #if defined(PETSC_USE_DEBUG) 4364 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); 4365 for (p = 0; p < 3; ++p) { 4366 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); 4367 } 4368 #endif 4369 supportNew[0] = (c - cStart)*8 + 1; 4370 supportNew[1] = (c - cStart)*8 + 1+4; 4371 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4372 #if defined(PETSC_USE_DEBUG) 4373 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4374 for (p = 0; p < 2; ++p) { 4375 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); 4376 } 4377 #endif 4378 ++newp; 4379 /* Face C: {c, f, b} */ 4380 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4381 orntNew[0] = ornt[2] < 0 ? -2 : 0; 4382 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4383 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4384 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 4385 orntNew[2] = ornt[0] < 0 ? -2 : 0; 4386 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4387 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4388 #if defined(PETSC_USE_DEBUG) 4389 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4390 for (p = 0; p < 3; ++p) { 4391 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); 4392 } 4393 #endif 4394 supportNew[0] = (c - cStart)*8 + 2; 4395 supportNew[1] = (c - cStart)*8 + 2+4; 4396 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4397 #if defined(PETSC_USE_DEBUG) 4398 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4399 for (p = 0; p < 2; ++p) { 4400 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); 4401 } 4402 #endif 4403 ++newp; 4404 /* Face D: {d, e, f} */ 4405 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 4406 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4407 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4408 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4409 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4410 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4411 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4412 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4413 #if defined(PETSC_USE_DEBUG) 4414 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4415 for (p = 0; p < 3; ++p) { 4416 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4417 } 4418 #endif 4419 supportNew[0] = (c - cStart)*8 + 3; 4420 supportNew[1] = (c - cStart)*8 + 3+4; 4421 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4422 #if defined(PETSC_USE_DEBUG) 4423 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4424 for (p = 0; p < 2; ++p) { 4425 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); 4426 } 4427 #endif 4428 ++newp; 4429 /* Face E: {d, f, a} */ 4430 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4431 orntNew[0] = ornt[2] < 0 ? 0 : -2; 4432 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4433 orntNew[1] = -2; 4434 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4435 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4436 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4437 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4438 #if defined(PETSC_USE_DEBUG) 4439 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4440 for (p = 0; p < 3; ++p) { 4441 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); 4442 } 4443 #endif 4444 supportNew[0] = (c - cStart)*8 + 0+4; 4445 supportNew[1] = (c - cStart)*8 + 3+4; 4446 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4447 #if defined(PETSC_USE_DEBUG) 4448 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4449 for (p = 0; p < 2; ++p) { 4450 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); 4451 } 4452 #endif 4453 ++newp; 4454 /* Face F: {c, a, f} */ 4455 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4456 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4457 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4458 orntNew[1] = 0; 4459 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4460 orntNew[2] = ornt[2] < 0 ? 0 : -2; 4461 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4462 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4463 #if defined(PETSC_USE_DEBUG) 4464 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4465 for (p = 0; p < 3; ++p) { 4466 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); 4467 } 4468 #endif 4469 supportNew[0] = (c - cStart)*8 + 0+4; 4470 supportNew[1] = (c - cStart)*8 + 2+4; 4471 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4472 #if defined(PETSC_USE_DEBUG) 4473 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4474 for (p = 0; p < 2; ++p) { 4475 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); 4476 } 4477 #endif 4478 ++newp; 4479 /* Face G: {e, a, f} */ 4480 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4481 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4482 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4483 orntNew[1] = 0; 4484 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4485 orntNew[2] = ornt[3] < 0 ? 0 : -2; 4486 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4487 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4488 #if defined(PETSC_USE_DEBUG) 4489 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4490 for (p = 0; p < 3; ++p) { 4491 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); 4492 } 4493 #endif 4494 supportNew[0] = (c - cStart)*8 + 1+4; 4495 supportNew[1] = (c - cStart)*8 + 3+4; 4496 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4497 #if defined(PETSC_USE_DEBUG) 4498 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4499 for (p = 0; p < 2; ++p) { 4500 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); 4501 } 4502 #endif 4503 ++newp; 4504 /* Face H: {a, b, f} */ 4505 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4506 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4507 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4508 orntNew[1] = ornt[3] < 0 ? 0 : -2; 4509 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4510 orntNew[2] = -2; 4511 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4512 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4513 #if defined(PETSC_USE_DEBUG) 4514 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4515 for (p = 0; p < 3; ++p) { 4516 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); 4517 } 4518 #endif 4519 supportNew[0] = (c - cStart)*8 + 1+4; 4520 supportNew[1] = (c - cStart)*8 + 2+4; 4521 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4522 #if defined(PETSC_USE_DEBUG) 4523 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4524 for (p = 0; p < 2; ++p) { 4525 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); 4526 } 4527 #endif 4528 ++newp; 4529 } 4530 /* Hybrid split faces have 4 edges and same cells */ 4531 for (f = fMax; f < fEnd; ++f) { 4532 const PetscInt *cone, *ornt, *support; 4533 PetscInt coneNew[4], orntNew[4]; 4534 PetscInt supportNew[2], size, s, c; 4535 4536 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4537 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4538 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4539 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4540 for (r = 0; r < 2; ++r) { 4541 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 4542 4543 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4544 orntNew[0] = ornt[0]; 4545 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4546 orntNew[1] = ornt[1]; 4547 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 4548 orntNew[2+r] = 0; 4549 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4550 orntNew[3-r] = 0; 4551 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4552 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4553 #if defined(PETSC_USE_DEBUG) 4554 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4555 for (p = 0; p < 2; ++p) { 4556 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); 4557 } 4558 for (p = 2; p < 4; ++p) { 4559 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); 4560 } 4561 #endif 4562 for (s = 0; s < size; ++s) { 4563 const PetscInt *coneCell, *orntCell, *fornt; 4564 PetscInt o, of; 4565 4566 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4567 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4568 o = orntCell[0] < 0 ? -1 : 1; 4569 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 4570 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 4571 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4572 of = fornt[c-2] < 0 ? -1 : 1; 4573 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 4574 } 4575 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4576 #if defined(PETSC_USE_DEBUG) 4577 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4578 for (p = 0; p < size; ++p) { 4579 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); 4580 } 4581 #endif 4582 } 4583 } 4584 /* Hybrid cell faces have 4 edges and 2 cells */ 4585 for (c = cMax; c < cEnd; ++c) { 4586 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 4587 const PetscInt *cone, *ornt; 4588 PetscInt coneNew[4], orntNew[4]; 4589 PetscInt supportNew[2]; 4590 4591 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4592 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4593 for (r = 0; r < 3; ++r) { 4594 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 4595 orntNew[0] = 0; 4596 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 4597 orntNew[1] = 0; 4598 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 4599 orntNew[2] = 0; 4600 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 4601 orntNew[3] = 0; 4602 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4603 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4604 #if defined(PETSC_USE_DEBUG) 4605 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); 4606 for (p = 0; p < 2; ++p) { 4607 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); 4608 } 4609 for (p = 2; p < 4; ++p) { 4610 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); 4611 } 4612 #endif 4613 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 4614 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 4615 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4616 #if defined(PETSC_USE_DEBUG) 4617 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); 4618 for (p = 0; p < 2; ++p) { 4619 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); 4620 } 4621 #endif 4622 } 4623 } 4624 /* Interior split edges have 2 vertices and the same faces as the parent */ 4625 for (e = eStart; e < eMax; ++e) { 4626 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4627 4628 for (r = 0; r < 2; ++r) { 4629 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4630 const PetscInt *cone, *ornt, *support; 4631 PetscInt coneNew[2], coneSize, c, supportSize, s; 4632 4633 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4634 coneNew[0] = vStartNew + (cone[0] - vStart); 4635 coneNew[1] = vStartNew + (cone[1] - vStart); 4636 coneNew[(r+1)%2] = newv; 4637 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4638 #if defined(PETSC_USE_DEBUG) 4639 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4640 for (p = 0; p < 2; ++p) { 4641 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); 4642 } 4643 #endif 4644 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4645 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4646 for (s = 0; s < supportSize; ++s) { 4647 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4648 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4649 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4650 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 4651 if (support[s] < fMax) { 4652 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4653 } else { 4654 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4655 } 4656 } 4657 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4658 #if defined(PETSC_USE_DEBUG) 4659 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4660 for (p = 0; p < supportSize; ++p) { 4661 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); 4662 } 4663 #endif 4664 } 4665 } 4666 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 4667 for (f = fStart; f < fMax; ++f) { 4668 const PetscInt *cone, *ornt, *support; 4669 PetscInt coneSize, supportSize, s; 4670 4671 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4672 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4673 for (r = 0; r < 3; ++r) { 4674 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 4675 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 4676 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 4677 -1, -1, 1, 6, 0, 4, 4678 2, 5, 3, 4, -1, -1, 4679 -1, -1, 3, 6, 2, 7}; 4680 4681 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4682 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4683 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4684 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4685 #if defined(PETSC_USE_DEBUG) 4686 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4687 for (p = 0; p < 2; ++p) { 4688 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); 4689 } 4690 #endif 4691 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4692 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4693 for (s = 0; s < supportSize; ++s) { 4694 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4695 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4696 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4697 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4698 if (support[s] < cMax) { 4699 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4700 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4701 if (er == eint[c]) { 4702 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4703 } else { 4704 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4705 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4706 } 4707 } else { 4708 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4709 } 4710 } 4711 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4712 #if defined(PETSC_USE_DEBUG) 4713 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4714 for (p = 0; p < intFaces; ++p) { 4715 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); 4716 } 4717 #endif 4718 } 4719 } 4720 /* Interior cell edges have 2 vertices and 4 faces */ 4721 for (c = cStart; c < cMax; ++c) { 4722 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4723 const PetscInt *cone, *ornt, *fcone; 4724 PetscInt coneNew[2], supportNew[4], find; 4725 4726 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4727 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4728 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4729 find = GetTriEdge_Static(ornt[0], 0); 4730 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4731 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4732 find = GetTriEdge_Static(ornt[2], 1); 4733 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4734 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4735 #if defined(PETSC_USE_DEBUG) 4736 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4737 for (p = 0; p < 2; ++p) { 4738 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); 4739 } 4740 #endif 4741 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4742 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4743 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4744 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4745 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4746 #if defined(PETSC_USE_DEBUG) 4747 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4748 for (p = 0; p < 4; ++p) { 4749 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); 4750 } 4751 #endif 4752 } 4753 /* Hybrid edges have two vertices and the same faces */ 4754 for (e = eMax; e < eEnd; ++e) { 4755 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4756 const PetscInt *cone, *support, *fcone; 4757 PetscInt coneNew[2], size, fsize, s; 4758 4759 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4760 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4761 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4762 coneNew[0] = vStartNew + (cone[0] - vStart); 4763 coneNew[1] = vStartNew + (cone[1] - vStart); 4764 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4765 #if defined(PETSC_USE_DEBUG) 4766 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4767 for (p = 0; p < 2; ++p) { 4768 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); 4769 } 4770 #endif 4771 for (s = 0; s < size; ++s) { 4772 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4773 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4774 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4775 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 4776 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4777 } 4778 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4779 #if defined(PETSC_USE_DEBUG) 4780 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4781 for (p = 0; p < size; ++p) { 4782 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); 4783 } 4784 #endif 4785 } 4786 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4787 for (f = fMax; f < fEnd; ++f) { 4788 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4789 const PetscInt *cone, *support, *ccone, *cornt; 4790 PetscInt coneNew[2], size, csize, s; 4791 4792 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4793 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4794 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4795 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4796 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4797 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4798 #if defined(PETSC_USE_DEBUG) 4799 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4800 for (p = 0; p < 2; ++p) { 4801 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); 4802 } 4803 #endif 4804 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4805 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4806 for (s = 0; s < size; ++s) { 4807 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4808 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4809 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4810 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4811 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]); 4812 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4813 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4814 } 4815 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4816 #if defined(PETSC_USE_DEBUG) 4817 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4818 for (p = 0; p < 2+size*2; ++p) { 4819 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); 4820 } 4821 #endif 4822 } 4823 /* Interior vertices have identical supports */ 4824 for (v = vStart; v < vEnd; ++v) { 4825 const PetscInt newp = vStartNew + (v - vStart); 4826 const PetscInt *support, *cone; 4827 PetscInt size, s; 4828 4829 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4830 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4831 for (s = 0; s < size; ++s) { 4832 PetscInt r = 0; 4833 4834 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4835 if (cone[1] == v) r = 1; 4836 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4837 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4838 } 4839 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4840 #if defined(PETSC_USE_DEBUG) 4841 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4842 for (p = 0; p < size; ++p) { 4843 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); 4844 } 4845 #endif 4846 } 4847 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4848 for (e = eStart; e < eMax; ++e) { 4849 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4850 const PetscInt *cone, *support; 4851 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4852 4853 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4854 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4855 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4856 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4857 for (s = 0; s < size; ++s) { 4858 PetscInt r = 0; 4859 4860 if (support[s] < fMax) { 4861 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4862 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4863 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4864 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4865 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4866 faceSize += 2; 4867 } else { 4868 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4869 ++faceSize; 4870 } 4871 } 4872 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4873 for (s = 0; s < starSize*2; s += 2) { 4874 const PetscInt *cone, *ornt; 4875 PetscInt e01, e23; 4876 4877 if ((star[s] >= cStart) && (star[s] < cMax)) { 4878 /* Check edge 0-1 */ 4879 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4880 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4881 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4882 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4883 /* Check edge 2-3 */ 4884 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4885 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4886 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4887 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4888 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 4889 } 4890 } 4891 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4892 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4893 #if defined(PETSC_USE_DEBUG) 4894 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4895 for (p = 0; p < 2+faceSize+cellSize; ++p) { 4896 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); 4897 } 4898 #endif 4899 } 4900 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4901 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4902 break; 4903 case REFINER_SIMPLEX_TO_HEX_3D: 4904 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4905 /* All cells have 6 faces */ 4906 for (c = cStart; c < cEnd; ++c) { 4907 const PetscInt newp = cStartNew + (c - cStart)*4; 4908 const PetscInt *cone, *ornt; 4909 PetscInt coneNew[6]; 4910 PetscInt orntNew[6]; 4911 4912 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4913 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4914 /* A hex */ 4915 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 4916 orntNew[0] = ornt[0] < 0 ? -1 : 1; 4917 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 4918 orntNew[1] = -4; 4919 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 4920 orntNew[2] = ornt[2] < 0 ? -1 : 1; 4921 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 4922 orntNew[3] = -1; 4923 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 4924 orntNew[4] = 0; 4925 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 4926 orntNew[5] = ornt[1] < 0 ? -1 : 1; 4927 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4928 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4929 #if defined(PETSC_USE_DEBUG) 4930 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); 4931 for (p = 0; p < 6; ++p) { 4932 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); 4933 } 4934 #endif 4935 /* B hex */ 4936 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 4937 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4938 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 4939 orntNew[1] = 0; 4940 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 4941 orntNew[2] = 0; 4942 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 4943 orntNew[3] = ornt[3] < 0 ? -2 : 0; 4944 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 4945 orntNew[4] = 0; 4946 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 4947 orntNew[5] = ornt[1] < 0 ? -4 : 2; 4948 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4949 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4950 #if defined(PETSC_USE_DEBUG) 4951 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); 4952 for (p = 0; p < 6; ++p) { 4953 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); 4954 } 4955 #endif 4956 /* C hex */ 4957 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 4958 orntNew[0] = ornt[0] < 0 ? -4 : 2; 4959 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 4960 orntNew[1] = -4; 4961 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 4962 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4963 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 4964 orntNew[3] = -1; 4965 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 4966 orntNew[4] = ornt[3] < 0 ? -1 : 1; 4967 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 4968 orntNew[5] = -4; 4969 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4970 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4971 #if defined(PETSC_USE_DEBUG) 4972 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); 4973 for (p = 0; p < 6; ++p) { 4974 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); 4975 } 4976 #endif 4977 /* D hex */ 4978 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 4979 orntNew[0] = 0; 4980 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 4981 orntNew[1] = ornt[3] < 0 ? -1 : 1; 4982 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 4983 orntNew[2] = ornt[2] < 0 ? -4 : 2; 4984 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 4985 orntNew[3] = -1; 4986 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 4987 orntNew[4] = 0; 4988 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 4989 orntNew[5] = ornt[1] < 0 ? -2 : 0; 4990 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4991 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4992 #if defined(PETSC_USE_DEBUG) 4993 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); 4994 for (p = 0; p < 6; ++p) { 4995 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); 4996 } 4997 #endif 4998 } 4999 /* Split faces have 4 edges and the same cells as the parent */ 5000 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5001 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5002 for (f = fStart; f < fEnd; ++f) { 5003 const PetscInt newp = fStartNew + (f - fStart)*3; 5004 const PetscInt *cone, *ornt, *support; 5005 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5006 5007 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5008 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5009 /* A quad */ 5010 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5011 orntNew[0] = ornt[2]; 5012 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5013 orntNew[1] = ornt[0]; 5014 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5015 orntNew[2] = 0; 5016 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5017 orntNew[3] = -2; 5018 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5019 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5020 #if defined(PETSC_USE_DEBUG) 5021 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); 5022 for (p = 0; p < 4; ++p) { 5023 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); 5024 } 5025 #endif 5026 /* B quad */ 5027 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5028 orntNew[0] = ornt[0]; 5029 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5030 orntNew[1] = ornt[1]; 5031 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5032 orntNew[2] = 0; 5033 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5034 orntNew[3] = -2; 5035 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5036 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5037 #if defined(PETSC_USE_DEBUG) 5038 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); 5039 for (p = 0; p < 4; ++p) { 5040 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); 5041 } 5042 #endif 5043 /* C quad */ 5044 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5045 orntNew[0] = ornt[1]; 5046 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5047 orntNew[1] = ornt[2]; 5048 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5049 orntNew[2] = 0; 5050 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5051 orntNew[3] = -2; 5052 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5053 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5054 #if defined(PETSC_USE_DEBUG) 5055 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); 5056 for (p = 0; p < 4; ++p) { 5057 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); 5058 } 5059 #endif 5060 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5061 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5062 for (r = 0; r < 3; ++r) { 5063 for (s = 0; s < supportSize; ++s) { 5064 PetscInt subf; 5065 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5066 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5067 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5068 for (c = 0; c < coneSize; ++c) { 5069 if (cone[c] == f) break; 5070 } 5071 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5072 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5073 } 5074 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5075 #if defined(PETSC_USE_DEBUG) 5076 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); 5077 for (p = 0; p < supportSize; ++p) { 5078 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); 5079 } 5080 #endif 5081 } 5082 } 5083 /* Interior faces have 4 edges and 2 cells */ 5084 for (c = cStart; c < cEnd; ++c) { 5085 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 5086 const PetscInt *cone, *ornt; 5087 PetscInt coneNew[4], orntNew[4]; 5088 PetscInt supportNew[2]; 5089 5090 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5091 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5092 /* Face {a, g, m, h} */ 5093 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5094 orntNew[0] = 0; 5095 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5096 orntNew[1] = 0; 5097 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5098 orntNew[2] = -2; 5099 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5100 orntNew[3] = -2; 5101 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5102 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5103 #if defined(PETSC_USE_DEBUG) 5104 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5105 for (p = 0; p < 4; ++p) { 5106 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); 5107 } 5108 #endif 5109 supportNew[0] = (c - cStart)*4 + 0; 5110 supportNew[1] = (c - cStart)*4 + 1; 5111 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5112 #if defined(PETSC_USE_DEBUG) 5113 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5114 for (p = 0; p < 2; ++p) { 5115 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); 5116 } 5117 #endif 5118 ++newp; 5119 /* Face {g, b, l , m} */ 5120 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5121 orntNew[0] = -2; 5122 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5123 orntNew[1] = 0; 5124 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5125 orntNew[2] = 0; 5126 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5127 orntNew[3] = -2; 5128 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5129 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5130 #if defined(PETSC_USE_DEBUG) 5131 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5132 for (p = 0; p < 4; ++p) { 5133 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); 5134 } 5135 #endif 5136 supportNew[0] = (c - cStart)*4 + 1; 5137 supportNew[1] = (c - cStart)*4 + 2; 5138 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5139 #if defined(PETSC_USE_DEBUG) 5140 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5141 for (p = 0; p < 2; ++p) { 5142 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); 5143 } 5144 #endif 5145 ++newp; 5146 /* Face {c, g, m, i} */ 5147 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5148 orntNew[0] = 0; 5149 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5150 orntNew[1] = 0; 5151 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5152 orntNew[2] = -2; 5153 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5154 orntNew[3] = -2; 5155 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5156 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5157 #if defined(PETSC_USE_DEBUG) 5158 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5159 for (p = 0; p < 4; ++p) { 5160 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5161 } 5162 #endif 5163 supportNew[0] = (c - cStart)*4 + 0; 5164 supportNew[1] = (c - cStart)*4 + 2; 5165 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5166 #if defined(PETSC_USE_DEBUG) 5167 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5168 for (p = 0; p < 2; ++p) { 5169 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); 5170 } 5171 #endif 5172 ++newp; 5173 /* Face {d, h, m, i} */ 5174 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5175 orntNew[0] = 0; 5176 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5177 orntNew[1] = 0; 5178 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5179 orntNew[2] = -2; 5180 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5181 orntNew[3] = -2; 5182 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5183 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5184 #if defined(PETSC_USE_DEBUG) 5185 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5186 for (p = 0; p < 4; ++p) { 5187 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); 5188 } 5189 #endif 5190 supportNew[0] = (c - cStart)*4 + 0; 5191 supportNew[1] = (c - cStart)*4 + 3; 5192 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5193 #if defined(PETSC_USE_DEBUG) 5194 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5195 for (p = 0; p < 2; ++p) { 5196 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); 5197 } 5198 #endif 5199 ++newp; 5200 /* Face {h, m, l, e} */ 5201 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5202 orntNew[0] = 0; 5203 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5204 orntNew[1] = -2; 5205 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 5206 orntNew[2] = -2; 5207 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 5208 orntNew[3] = 0; 5209 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5210 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5211 #if defined(PETSC_USE_DEBUG) 5212 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5213 for (p = 0; p < 4; ++p) { 5214 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); 5215 } 5216 #endif 5217 supportNew[0] = (c - cStart)*4 + 1; 5218 supportNew[1] = (c - cStart)*4 + 3; 5219 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5220 #if defined(PETSC_USE_DEBUG) 5221 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5222 for (p = 0; p < 2; ++p) { 5223 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); 5224 } 5225 #endif 5226 ++newp; 5227 /* Face {i, m, l, f} */ 5228 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5229 orntNew[0] = 0; 5230 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5231 orntNew[1] = -2; 5232 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 5233 orntNew[2] = -2; 5234 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 5235 orntNew[3] = 0; 5236 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5237 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5238 #if defined(PETSC_USE_DEBUG) 5239 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5240 for (p = 0; p < 4; ++p) { 5241 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); 5242 } 5243 #endif 5244 supportNew[0] = (c - cStart)*4 + 2; 5245 supportNew[1] = (c - cStart)*4 + 3; 5246 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5247 #if defined(PETSC_USE_DEBUG) 5248 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5249 for (p = 0; p < 2; ++p) { 5250 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); 5251 } 5252 #endif 5253 ++newp; 5254 } 5255 /* Split Edges have 2 vertices and the same faces as the parent */ 5256 for (e = eStart; e < eEnd; ++e) { 5257 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5258 5259 for (r = 0; r < 2; ++r) { 5260 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5261 const PetscInt *cone, *ornt, *support; 5262 PetscInt coneNew[2], coneSize, c, supportSize, s; 5263 5264 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5265 coneNew[0] = vStartNew + (cone[0] - vStart); 5266 coneNew[1] = vStartNew + (cone[1] - vStart); 5267 coneNew[(r+1)%2] = newv; 5268 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5269 #if defined(PETSC_USE_DEBUG) 5270 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5271 for (p = 0; p < 2; ++p) { 5272 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); 5273 } 5274 #endif 5275 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5276 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5277 for (s = 0; s < supportSize; ++s) { 5278 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5279 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5280 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5281 for (c = 0; c < coneSize; ++c) { 5282 if (cone[c] == e) break; 5283 } 5284 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 5285 } 5286 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5287 #if defined(PETSC_USE_DEBUG) 5288 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5289 for (p = 0; p < supportSize; ++p) { 5290 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); 5291 } 5292 #endif 5293 } 5294 } 5295 /* Face edges have 2 vertices and 2 + cell faces supports */ 5296 for (f = fStart; f < fEnd; ++f) { 5297 const PetscInt *cone, *ornt, *support; 5298 PetscInt coneSize, supportSize, s; 5299 5300 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5301 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5302 for (r = 0; r < 3; ++r) { 5303 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 5304 PetscInt coneNew[2]; 5305 PetscInt fint[4][3] = { {0, 1, 2}, 5306 {3, 4, 0}, 5307 {2, 5, 3}, 5308 {1, 4, 5} }; 5309 5310 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5311 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5312 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 5313 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5314 #if defined(PETSC_USE_DEBUG) 5315 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5316 for (p = 0; p < 2; ++p) { 5317 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); 5318 } 5319 #endif 5320 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 5321 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 5322 for (s = 0; s < supportSize; ++s) { 5323 PetscInt er; 5324 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5325 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5326 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5327 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 5328 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 5329 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 5330 } 5331 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5332 #if defined(PETSC_USE_DEBUG) 5333 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5334 for (p = 0; p < supportSize + 2; ++p) { 5335 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); 5336 } 5337 #endif 5338 } 5339 } 5340 /* Interior cell edges have 2 vertices and 3 faces */ 5341 for (c = cStart; c < cEnd; ++c) { 5342 const PetscInt *cone; 5343 PetscInt fint[4][3] = { {0,1,2}, 5344 {0,3,4}, 5345 {2,3,5}, 5346 {1,4,5} } ; 5347 5348 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5349 for (r = 0; r < 4; r++) { 5350 PetscInt coneNew[2], supportNew[3]; 5351 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 5352 5353 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5354 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 5355 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5356 #if defined(PETSC_USE_DEBUG) 5357 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5358 for (p = 0; p < 2; ++p) { 5359 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); 5360 } 5361 #endif 5362 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 5363 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 5364 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 5365 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5366 #if defined(PETSC_USE_DEBUG) 5367 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5368 for (p = 0; p < 3; ++p) { 5369 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); 5370 } 5371 #endif 5372 } 5373 } 5374 /* Old vertices have identical supports */ 5375 for (v = vStart; v < vEnd; ++v) { 5376 const PetscInt newp = vStartNew + (v - vStart); 5377 const PetscInt *support, *cone; 5378 PetscInt size, s; 5379 5380 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5381 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5382 for (s = 0; s < size; ++s) { 5383 PetscInt r = 0; 5384 5385 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5386 if (cone[1] == v) r = 1; 5387 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5388 } 5389 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5390 #if defined(PETSC_USE_DEBUG) 5391 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5392 for (p = 0; p < size; ++p) { 5393 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); 5394 } 5395 #endif 5396 } 5397 /* Edge vertices have 2 + faces supports */ 5398 for (e = eStart; e < eEnd; ++e) { 5399 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5400 const PetscInt *cone, *support; 5401 PetscInt size, s; 5402 5403 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5404 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5405 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5406 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5407 for (s = 0; s < size; ++s) { 5408 PetscInt r = 0, coneSize; 5409 5410 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5411 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5412 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 5413 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 5414 } 5415 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5416 #if defined(PETSC_USE_DEBUG) 5417 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5418 for (p = 0; p < 2+size; ++p) { 5419 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); 5420 } 5421 #endif 5422 } 5423 /* Face vertices have 3 + cells supports */ 5424 for (f = fStart; f < fEnd; ++f) { 5425 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5426 const PetscInt *cone, *support; 5427 PetscInt size, s; 5428 5429 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5430 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5431 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5432 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5433 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5434 for (s = 0; s < size; ++s) { 5435 PetscInt r = 0, coneSize; 5436 5437 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5438 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5439 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 5440 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 5441 } 5442 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5443 #if defined(PETSC_USE_DEBUG) 5444 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5445 for (p = 0; p < 3+size; ++p) { 5446 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); 5447 } 5448 #endif 5449 } 5450 /* Interior cell vertices have 4 supports */ 5451 for (c = cStart; c < cEnd; ++c) { 5452 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 5453 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5454 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5455 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5456 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5457 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5458 #if defined(PETSC_USE_DEBUG) 5459 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5460 for (p = 0; p < 4; ++p) { 5461 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); 5462 } 5463 #endif 5464 } 5465 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5466 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5467 break; 5468 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 5469 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 5470 cMax = PetscMin(cEnd, cMax); 5471 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5472 fMax = PetscMin(fEnd, fMax); 5473 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5474 eMax = PetscMin(eEnd, eMax); 5475 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5476 /* All cells have 6 faces */ 5477 for (c = cStart; c < cMax; ++c) { 5478 const PetscInt newp = cStartNew + (c - cStart)*4; 5479 const PetscInt *cone, *ornt; 5480 PetscInt coneNew[6]; 5481 PetscInt orntNew[6]; 5482 5483 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5484 #if defined(PETSC_USE_DEBUG) 5485 for (p = 0; p < 4; ++p) { 5486 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); 5487 } 5488 #endif 5489 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5490 /* A hex */ 5491 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5492 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5493 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5494 orntNew[1] = -4; 5495 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5496 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5497 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5498 orntNew[3] = -1; 5499 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5500 orntNew[4] = 0; 5501 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5502 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5503 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5504 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5505 #if defined(PETSC_USE_DEBUG) 5506 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); 5507 for (p = 0; p < 6; ++p) { 5508 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); 5509 } 5510 #endif 5511 /* B hex */ 5512 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5513 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5514 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5515 orntNew[1] = 0; 5516 coneNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5517 orntNew[2] = 0; 5518 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5519 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5520 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5521 orntNew[4] = 0; 5522 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5523 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5524 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5525 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5526 #if defined(PETSC_USE_DEBUG) 5527 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); 5528 for (p = 0; p < 6; ++p) { 5529 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); 5530 } 5531 #endif 5532 /* C hex */ 5533 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5534 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5535 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5536 orntNew[1] = -4; 5537 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5538 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5539 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5540 orntNew[3] = -1; 5541 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5542 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5543 coneNew[5] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5544 orntNew[5] = -4; 5545 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5546 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5547 #if defined(PETSC_USE_DEBUG) 5548 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); 5549 for (p = 0; p < 6; ++p) { 5550 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); 5551 } 5552 #endif 5553 /* D hex */ 5554 coneNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5555 orntNew[0] = 0; 5556 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5557 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5558 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5559 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5560 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5561 orntNew[3] = -1; 5562 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5563 orntNew[4] = 0; 5564 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5565 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5566 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5567 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5568 #if defined(PETSC_USE_DEBUG) 5569 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); 5570 for (p = 0; p < 6; ++p) { 5571 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); 5572 } 5573 #endif 5574 } 5575 for (c = cMax; c < cEnd; ++c) { 5576 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3; 5577 const PetscInt *cone, *ornt, *fornt; 5578 PetscInt coneNew[6], orntNew[6]; 5579 PetscInt o, of, cf; 5580 5581 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5582 #if defined(PETSC_USE_DEBUG) 5583 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); 5584 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); 5585 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); 5586 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); 5587 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); 5588 #endif 5589 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5590 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 5591 o = ornt[0] < 0 ? -1 : 1; 5592 /* A hex */ 5593 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5594 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5595 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* T */ 5596 orntNew[1] = ornt[1] < 0 ? 1 : -1; 5597 cf = GetTriEdge_Static(ornt[0], 2); 5598 of = fornt[cf] < 0 ? -1 : 1; 5599 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* F */ 5600 orntNew[2] = o*of < 0 ? 0 : -1; 5601 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* K */ 5602 orntNew[3] = -1; 5603 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* R */ 5604 orntNew[4] = 0; 5605 cf = GetTriEdge_Static(ornt[0], 0); 5606 of = fornt[cf] < 0 ? -1 : 1; 5607 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* L */ 5608 orntNew[5] = o*of < 0 ? 1 : -4; 5609 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5610 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5611 #if defined(PETSC_USE_DEBUG) 5612 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); 5613 for (p = 0; p < 6; ++p) { 5614 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); 5615 } 5616 #endif 5617 /* B hex */ 5618 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5619 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5620 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* T */ 5621 orntNew[1] = ornt[1] < 0 ? 2 : -4; 5622 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* F */ 5623 orntNew[2] = 0; 5624 cf = GetTriEdge_Static(ornt[0], 1); 5625 of = fornt[cf] < 0 ? -1 : 1; 5626 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* K */ 5627 orntNew[3] = o*of < 0 ? 0 : -1; 5628 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* R */ 5629 orntNew[4] = -1; 5630 cf = GetTriEdge_Static(ornt[0], 0); 5631 of = fornt[cf] < 0 ? -1 : 1; 5632 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* L */ 5633 orntNew[5] = o*of < 0 ? 1 : -4; 5634 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5635 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5636 #if defined(PETSC_USE_DEBUG) 5637 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); 5638 for (p = 0; p < 6; ++p) { 5639 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); 5640 } 5641 #endif 5642 /* C hex */ 5643 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5644 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5645 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* T */ 5646 orntNew[1] = ornt[1] < 0 ? 0 : -2; 5647 cf = GetTriEdge_Static(ornt[0], 2); 5648 of = fornt[cf] < 0 ? -1 : 1; 5649 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* F */ 5650 orntNew[2] = o*of < 0 ? 0 : -1; 5651 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* K */ 5652 orntNew[3] = 0; 5653 cf = GetTriEdge_Static(ornt[0], 1); 5654 of = fornt[cf] < 0 ? -1 : 1; 5655 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* R */ 5656 orntNew[4] = o*of < 0 ? 0 : -1; 5657 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* L */ 5658 orntNew[5] = -4; 5659 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5660 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5661 #if defined(PETSC_USE_DEBUG) 5662 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); 5663 for (p = 0; p < 6; ++p) { 5664 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); 5665 } 5666 #endif 5667 } 5668 5669 /* Split faces have 4 edges and the same cells as the parent */ 5670 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5671 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5672 for (f = fStart; f < fMax; ++f) { 5673 const PetscInt newp = fStartNew + (f - fStart)*3; 5674 const PetscInt *cone, *ornt, *support; 5675 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5676 5677 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5678 #if defined(PETSC_USE_DEBUG) 5679 for (p = 0; p < 3; ++p) { 5680 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); 5681 } 5682 #endif 5683 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5684 /* A quad */ 5685 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5686 orntNew[0] = ornt[2]; 5687 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5688 orntNew[1] = ornt[0]; 5689 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5690 orntNew[2] = 0; 5691 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5692 orntNew[3] = -2; 5693 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5694 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5695 #if defined(PETSC_USE_DEBUG) 5696 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); 5697 for (p = 0; p < 4; ++p) { 5698 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); 5699 } 5700 #endif 5701 /* B quad */ 5702 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5703 orntNew[0] = ornt[0]; 5704 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5705 orntNew[1] = ornt[1]; 5706 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5707 orntNew[2] = 0; 5708 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5709 orntNew[3] = -2; 5710 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5711 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5712 #if defined(PETSC_USE_DEBUG) 5713 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); 5714 for (p = 0; p < 4; ++p) { 5715 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); 5716 } 5717 #endif 5718 /* C quad */ 5719 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5720 orntNew[0] = ornt[1]; 5721 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5722 orntNew[1] = ornt[2]; 5723 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5724 orntNew[2] = 0; 5725 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5726 orntNew[3] = -2; 5727 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5728 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5729 #if defined(PETSC_USE_DEBUG) 5730 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); 5731 for (p = 0; p < 4; ++p) { 5732 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); 5733 } 5734 #endif 5735 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5736 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5737 for (r = 0; r < 3; ++r) { 5738 for (s = 0; s < supportSize; ++s) { 5739 PetscInt subf; 5740 5741 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5742 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); 5743 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); 5744 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5745 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5746 for (c = 0; c < coneSize; ++c) { 5747 if (cone[c] == f) break; 5748 } 5749 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5750 if (coneSize == 4) { 5751 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5752 } else if (coneSize == 5) { 5753 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); 5754 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + subf; 5755 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5756 } 5757 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5758 #if defined(PETSC_USE_DEBUG) 5759 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); 5760 for (p = 0; p < supportSize; ++p) { 5761 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); 5762 } 5763 #endif 5764 } 5765 } 5766 /* Interior faces have 4 edges and 2 cells */ 5767 for (c = cStart; c < cMax; ++c) { 5768 PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6; 5769 const PetscInt *cone, *ornt; 5770 PetscInt coneNew[4], orntNew[4]; 5771 PetscInt supportNew[2]; 5772 5773 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5774 #if defined(PETSC_USE_DEBUG) 5775 for (p = 0; p < 4; ++p) { 5776 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); 5777 } 5778 #endif 5779 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5780 /* Face {a, g, m, h} */ 5781 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5782 orntNew[0] = 0; 5783 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5784 orntNew[1] = 0; 5785 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5786 orntNew[2] = -2; 5787 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5788 orntNew[3] = -2; 5789 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5790 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5791 #if defined(PETSC_USE_DEBUG) 5792 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5793 for (p = 0; p < 4; ++p) { 5794 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); 5795 } 5796 #endif 5797 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5798 supportNew[1] = cStartNew + (c - cStart)*4 + 1; 5799 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5800 #if defined(PETSC_USE_DEBUG) 5801 for (p = 0; p < 2; ++p) { 5802 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); 5803 } 5804 #endif 5805 ++newp; 5806 /* Face {g, b, l , m} */ 5807 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5808 orntNew[0] = -2; 5809 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5810 orntNew[1] = 0; 5811 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5812 orntNew[2] = 0; 5813 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5814 orntNew[3] = -2; 5815 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5816 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5817 #if defined(PETSC_USE_DEBUG) 5818 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5819 for (p = 0; p < 4; ++p) { 5820 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); 5821 } 5822 #endif 5823 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 5824 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5825 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5826 #if defined(PETSC_USE_DEBUG) 5827 for (p = 0; p < 2; ++p) { 5828 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); 5829 } 5830 #endif 5831 ++newp; 5832 /* Face {c, g, m, i} */ 5833 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5834 orntNew[0] = 0; 5835 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5836 orntNew[1] = 0; 5837 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5838 orntNew[2] = -2; 5839 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5840 orntNew[3] = -2; 5841 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5842 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5843 #if defined(PETSC_USE_DEBUG) 5844 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5845 for (p = 0; p < 4; ++p) { 5846 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); 5847 } 5848 #endif 5849 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5850 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5851 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5852 #if defined(PETSC_USE_DEBUG) 5853 for (p = 0; p < 2; ++p) { 5854 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); 5855 } 5856 #endif 5857 ++newp; 5858 /* Face {d, h, m, i} */ 5859 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5860 orntNew[0] = 0; 5861 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5862 orntNew[1] = 0; 5863 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5864 orntNew[2] = -2; 5865 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5866 orntNew[3] = -2; 5867 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5868 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5869 #if defined(PETSC_USE_DEBUG) 5870 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5871 for (p = 0; p < 4; ++p) { 5872 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); 5873 } 5874 #endif 5875 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5876 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 5877 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5878 #if defined(PETSC_USE_DEBUG) 5879 for (p = 0; p < 2; ++p) { 5880 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); 5881 } 5882 #endif 5883 ++newp; 5884 /* Face {h, m, l, e} */ 5885 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5886 orntNew[0] = 0; 5887 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5888 orntNew[1] = -2; 5889 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 5890 orntNew[2] = -2; 5891 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 5892 orntNew[3] = 0; 5893 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5894 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5895 #if defined(PETSC_USE_DEBUG) 5896 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5897 for (p = 0; p < 4; ++p) { 5898 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); 5899 } 5900 #endif 5901 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 5902 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 5903 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5904 #if defined(PETSC_USE_DEBUG) 5905 for (p = 0; p < 2; ++p) { 5906 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); 5907 } 5908 #endif 5909 ++newp; 5910 /* Face {i, m, l, f} */ 5911 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5912 orntNew[0] = 0; 5913 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5914 orntNew[1] = -2; 5915 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 5916 orntNew[2] = -2; 5917 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 5918 orntNew[3] = 0; 5919 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5920 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5921 #if defined(PETSC_USE_DEBUG) 5922 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5923 for (p = 0; p < 4; ++p) { 5924 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); 5925 } 5926 #endif 5927 supportNew[0] = cStartNew + (c - cStart)*4 + 2; 5928 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 5929 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5930 #if defined(PETSC_USE_DEBUG) 5931 for (p = 0; p < 2; ++p) { 5932 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); 5933 } 5934 #endif 5935 ++newp; 5936 } 5937 /* Hybrid split faces have 4 edges and same cells */ 5938 for (f = fMax; f < fEnd; ++f) { 5939 const PetscInt *cone, *ornt, *support; 5940 PetscInt coneNew[4], orntNew[4]; 5941 PetscInt size, s; 5942 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2; 5943 5944 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5945 #if defined(PETSC_USE_DEBUG) 5946 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); 5947 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); 5948 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); 5949 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); 5950 #endif 5951 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5952 /* A face */ 5953 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5954 orntNew[0] = ornt[0]; 5955 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 5956 orntNew[1] = 0; 5957 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5958 orntNew[2] = ornt[1] < 0 ? 0 : -2; 5959 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[2] - eMax); 5960 orntNew[3] = ornt[2] < 0 ? 0 : -2; 5961 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5962 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5963 #if defined(PETSC_USE_DEBUG) 5964 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5965 for (p = 0; p < 4; ++p) { 5966 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5967 } 5968 #endif 5969 5970 /* B face */ 5971 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5972 orntNew[0] = ornt[0]; 5973 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[3] - eMax); 5974 orntNew[1] = ornt[3]; 5975 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5976 orntNew[2] = ornt[1] < 0 ? 0 : -2; 5977 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 5978 orntNew[3] = -2; 5979 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5980 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5981 #if defined(PETSC_USE_DEBUG) 5982 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); 5983 for (p = 0; p < 4; ++p) { 5984 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); 5985 } 5986 #endif 5987 5988 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5989 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5990 for (r = 0; r < 2; ++r) { 5991 for (s = 0; s < size; ++s) { 5992 const PetscInt *coneCell, *orntCell, *fornt; 5993 PetscInt coneSize, o, of, c; 5994 5995 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5996 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); 5997 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5998 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5999 o = orntCell[0] < 0 ? -1 : 1; 6000 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 6001 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); 6002 if (c == coneSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 6003 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 6004 of = fornt[c-2] < 0 ? -1 : 1; 6005 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 6006 } 6007 ierr = DMPlexSetSupport(rdm, newp + r, supportRef);CHKERRQ(ierr); 6008 #if defined(PETSC_USE_DEBUG) 6009 for (p = 0; p < size; ++p) { 6010 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); 6011 } 6012 #endif 6013 } 6014 } 6015 /* Interior hybrid faces have 4 edges and 2 cells */ 6016 for (c = cMax; c < cEnd; ++c) { 6017 PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3; 6018 const PetscInt *cone, *ornt; 6019 PetscInt coneNew[4], orntNew[4]; 6020 PetscInt supportNew[2]; 6021 6022 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6023 #if defined(PETSC_USE_DEBUG) 6024 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); 6025 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); 6026 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); 6027 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); 6028 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); 6029 #endif 6030 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6031 /* Face {a, g, h, d} */ 6032 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 6033 orntNew[0] = 0; 6034 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6035 orntNew[1] = 0; 6036 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 6037 orntNew[2] = -2; 6038 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[2] - fMax); 6039 orntNew[3] = -2; 6040 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6041 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6042 #if defined(PETSC_USE_DEBUG) 6043 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6044 for (p = 0; p < 4; ++p) { 6045 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); 6046 } 6047 #endif 6048 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6049 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6050 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6051 #if defined(PETSC_USE_DEBUG) 6052 for (p = 0; p < 2; ++p) { 6053 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); 6054 } 6055 #endif 6056 ++newp; 6057 /* Face {b, g, h, l} */ 6058 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 6059 orntNew[0] = 0; 6060 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6061 orntNew[1] = 0; 6062 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6063 orntNew[2] = -2; 6064 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[3] - fMax); 6065 orntNew[3] = -2; 6066 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6067 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6068 #if defined(PETSC_USE_DEBUG) 6069 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6070 for (p = 0; p < 4; ++p) { 6071 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); 6072 } 6073 #endif 6074 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6075 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6076 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6077 #if defined(PETSC_USE_DEBUG) 6078 for (p = 0; p < 2; ++p) { 6079 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); 6080 } 6081 #endif 6082 ++newp; 6083 /* Face {c, g, h, f} */ 6084 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 6085 orntNew[0] = 0; 6086 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6087 orntNew[1] = 0; 6088 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 6089 orntNew[2] = -2; 6090 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[4] - fMax); 6091 orntNew[3] = -2; 6092 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6093 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6094 #if defined(PETSC_USE_DEBUG) 6095 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6096 for (p = 0; p < 4; ++p) { 6097 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); 6098 } 6099 #endif 6100 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6101 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6102 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6103 #if defined(PETSC_USE_DEBUG) 6104 for (p = 0; p < 2; ++p) { 6105 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); 6106 } 6107 #endif 6108 } 6109 /* Face edges have 2 vertices and 2 + cell faces supports */ 6110 for (f = fStart; f < fMax; ++f) { 6111 const PetscInt *cone, *ornt, *support; 6112 PetscInt coneSize, supportSize, s; 6113 6114 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6115 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6116 for (r = 0; r < 3; ++r) { 6117 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 6118 PetscInt coneNew[2]; 6119 PetscInt fint[4][3] = { {0, 1, 2}, 6120 {3, 4, 0}, 6121 {2, 5, 3}, 6122 {1, 4, 5} }; 6123 6124 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6125 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); 6126 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6127 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 6128 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6129 #if defined(PETSC_USE_DEBUG) 6130 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6131 for (p = 0; p < 2; ++p) { 6132 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); 6133 } 6134 #endif 6135 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 6136 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 6137 for (s = 0; s < supportSize; ++s) { 6138 PetscInt er; 6139 6140 supportRef[2+s] = -1; 6141 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6142 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); 6143 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); 6144 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6145 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6146 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6147 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 6148 if (coneSize == 4) { 6149 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 6150 } else if (coneSize == 5) { 6151 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); 6152 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + er; 6153 } 6154 } 6155 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6156 #if defined(PETSC_USE_DEBUG) 6157 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6158 for (p = 0; p < supportSize + 2; ++p) { 6159 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); 6160 } 6161 #endif 6162 } 6163 } 6164 /* Interior cell edges have 2 vertices and 3 faces */ 6165 for (c = cStart; c < cMax; ++c) { 6166 const PetscInt *cone; 6167 PetscInt fint[4][3] = { {0,1,2}, 6168 {0,3,4}, 6169 {2,3,5}, 6170 {1,4,5} } ; 6171 6172 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6173 for (r = 0; r < 4; r++) { 6174 PetscInt coneNew[2], supportNew[3]; 6175 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 6176 6177 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); 6178 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6179 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax -fStart) + c - cStart; 6180 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6181 #if defined(PETSC_USE_DEBUG) 6182 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6183 for (p = 0; p < 2; ++p) { 6184 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); 6185 } 6186 #endif 6187 supportNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][0]; 6188 supportNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][1]; 6189 supportNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][2]; 6190 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6191 #if defined(PETSC_USE_DEBUG) 6192 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6193 for (p = 0; p < 3; ++p) { 6194 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); 6195 } 6196 #endif 6197 } 6198 } 6199 /* Hybrid edges have two vertices and the same faces */ 6200 for (e = eMax; e < eEnd; ++e) { 6201 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 6202 const PetscInt *cone, *support, *fcone; 6203 PetscInt coneNew[2], size, fsize, s; 6204 6205 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6206 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6207 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6208 coneNew[0] = vStartNew + (cone[0] - vStart); 6209 coneNew[1] = vStartNew + (cone[1] - vStart); 6210 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6211 #if defined(PETSC_USE_DEBUG) 6212 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is a edge [%D, %D)", newp, eStartNew, eEndNew); 6213 for (p = 0; p < 2; ++p) { 6214 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); 6215 } 6216 #endif 6217 for (s = 0; s < size; ++s) { 6218 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6219 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6220 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6221 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 6222 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + c-2; 6223 } 6224 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6225 #if defined(PETSC_USE_DEBUG) 6226 for (p = 0; p < size; ++p) { 6227 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); 6228 } 6229 #endif 6230 } 6231 /* Hybrid face edges have 2 vertices and 2 + cell faces supports */ 6232 for (f = fMax; f < fEnd; ++f) { 6233 const PetscInt *cone, *ornt, *support; 6234 PetscInt coneSize, supportSize; 6235 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + f - fMax; 6236 PetscInt coneNew[2], s; 6237 6238 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6239 #if defined(PETSC_USE_DEBUG) 6240 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); 6241 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); 6242 #endif 6243 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6244 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6245 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6246 #if defined(PETSC_USE_DEBUG) 6247 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6248 for (p = 0; p < 2; ++p) { 6249 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); 6250 } 6251 #endif 6252 supportRef[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 0; 6253 supportRef[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 1; 6254 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6255 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6256 for (s = 0; s < supportSize; ++s) { 6257 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6258 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); 6259 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6260 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6261 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6262 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); 6263 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c - 2; 6264 } 6265 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6266 #if defined(PETSC_USE_DEBUG) 6267 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6268 for (p = 0; p < supportSize + 2; ++p) { 6269 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); 6270 } 6271 #endif 6272 } 6273 /* Hybrid cell edges have 2 vertices and 3 faces */ 6274 for (c = cMax; c < cEnd; ++c) { 6275 PetscInt coneNew[2], supportNew[3]; 6276 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6277 const PetscInt *cone; 6278 6279 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6280 #if defined(PETSC_USE_DEBUG) 6281 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); 6282 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); 6283 #endif 6284 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6285 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6286 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6287 #if defined(PETSC_USE_DEBUG) 6288 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6289 for (p = 0; p < 2; ++p) { 6290 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); 6291 } 6292 #endif 6293 supportNew[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 6294 supportNew[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 6295 supportNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 6296 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6297 #if defined(PETSC_USE_DEBUG) 6298 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6299 for (p = 0; p < 3; ++p) { 6300 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); 6301 } 6302 #endif 6303 } 6304 /* Old vertices have identical supports */ 6305 for (v = vStart; v < vEnd; ++v) { 6306 const PetscInt newp = vStartNew + (v - vStart); 6307 const PetscInt *support, *cone; 6308 PetscInt size, s; 6309 6310 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6311 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6312 for (s = 0; s < size; ++s) { 6313 const PetscInt e = support[s]; 6314 6315 supportRef[s] = -1; 6316 if (eStart <= e) { 6317 if (e < eMax) { 6318 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6319 supportRef[s] = eStartNew + (e - eStart)*2 + (cone[1] == v ? 1 : 0); 6320 } else if (e < eEnd) { 6321 supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + e - eMax; 6322 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6323 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6324 } 6325 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6326 #if defined(PETSC_USE_DEBUG) 6327 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6328 for (p = 0; p < size; ++p) { 6329 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); 6330 } 6331 #endif 6332 } 6333 /* Interior edge vertices have 2 + faces supports */ 6334 for (e = eStart; e < eMax; ++e) { 6335 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6336 const PetscInt *cone, *support; 6337 PetscInt size, s; 6338 6339 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6340 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6341 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6342 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6343 for (s = 0; s < size; ++s) { 6344 PetscInt r, coneSize; 6345 6346 supportRef[2+s] = -1; 6347 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6348 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); 6349 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); 6350 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6351 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 6352 if (coneSize == 3) supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + r; 6353 else if (coneSize == 4) { 6354 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); 6355 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + support[s] - fMax; 6356 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6357 } 6358 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6359 #if defined(PETSC_USE_DEBUG) 6360 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6361 for (p = 0; p < 2+size; ++p) { 6362 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); 6363 } 6364 #endif 6365 } 6366 /* Split Edges have 2 vertices and the same faces as the parent */ 6367 for (e = eStart; e < eMax; ++e) { 6368 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6369 6370 for (r = 0; r < 2; ++r) { 6371 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6372 const PetscInt *cone, *ornt, *support; 6373 PetscInt coneNew[2], coneSize, c, supportSize, s; 6374 6375 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6376 coneNew[0] = vStartNew + (cone[0] - vStart); 6377 coneNew[1] = vStartNew + (cone[1] - vStart); 6378 coneNew[(r+1)%2] = newv; 6379 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6380 #if defined(PETSC_USE_DEBUG) 6381 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6382 for (p = 0; p < 2; ++p) { 6383 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); 6384 } 6385 #endif 6386 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6387 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6388 for (s = 0; s < supportSize; ++s) { 6389 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6390 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); 6391 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); 6392 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6393 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6394 for (c = 0; c < coneSize; ++c) { 6395 if (cone[c] == e) break; 6396 } 6397 if (coneSize == 3) supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 6398 else if (coneSize == 4) { 6399 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); 6400 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6401 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6402 } 6403 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6404 #if defined(PETSC_USE_DEBUG) 6405 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6406 for (p = 0; p < supportSize; ++p) { 6407 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); 6408 } 6409 #endif 6410 } 6411 } 6412 /* Face vertices have 3 + cells supports */ 6413 for (f = fStart; f < fMax; ++f) { 6414 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6415 const PetscInt *cone, *support; 6416 PetscInt size, s; 6417 6418 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6419 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6420 supportRef[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 6421 supportRef[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 6422 supportRef[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 6423 for (s = 0; s < size; ++s) { 6424 PetscInt r, coneSize; 6425 6426 supportRef[3+s] = -1; 6427 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6428 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); 6429 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); 6430 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6431 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 6432 if (coneSize == 4) supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (support[s] - cStart)*4 + r; 6433 else if (coneSize == 5) { 6434 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); 6435 supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + support[s] - cMax; 6436 } 6437 } 6438 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6439 #if defined(PETSC_USE_DEBUG) 6440 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6441 for (p = 0; p < 3+size; ++p) { 6442 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); 6443 } 6444 #endif 6445 } 6446 /* Interior cell vertices have 4 supports */ 6447 for (c = cStart; c < cMax; ++c) { 6448 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 6449 6450 supportRef[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 6451 supportRef[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6452 supportRef[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6453 supportRef[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 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 < 4; ++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 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6463 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 6464 break; 6465 case REFINER_HEX_3D: 6466 /* 6467 Bottom (viewed from top) Top 6468 1---------2---------2 7---------2---------6 6469 | | | | | | 6470 | B 2 C | | H 2 G | 6471 | | | | | | 6472 3----3----0----1----1 3----3----0----1----1 6473 | | | | | | 6474 | A 0 D | | E 0 F | 6475 | | | | | | 6476 0---------0---------3 4---------0---------5 6477 */ 6478 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 6479 for (c = cStart; c < cEnd; ++c) { 6480 const PetscInt newp = (c - cStart)*8; 6481 const PetscInt *cone, *ornt; 6482 PetscInt coneNew[6], orntNew[6]; 6483 6484 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6485 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6486 /* A hex */ 6487 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 6488 orntNew[0] = ornt[0]; 6489 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6490 orntNew[1] = 0; 6491 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 6492 orntNew[2] = ornt[2]; 6493 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6494 orntNew[3] = 0; 6495 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6496 orntNew[4] = 0; 6497 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 6498 orntNew[5] = ornt[5]; 6499 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 6500 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 6501 #if defined(PETSC_USE_DEBUG) 6502 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); 6503 for (p = 0; p < 6; ++p) { 6504 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); 6505 } 6506 #endif 6507 /* B hex */ 6508 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 6509 orntNew[0] = ornt[0]; 6510 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6511 orntNew[1] = 0; 6512 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6513 orntNew[2] = -1; 6514 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 6515 orntNew[3] = ornt[3]; 6516 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6517 orntNew[4] = 0; 6518 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 6519 orntNew[5] = ornt[5]; 6520 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6521 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6522 #if defined(PETSC_USE_DEBUG) 6523 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); 6524 for (p = 0; p < 6; ++p) { 6525 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); 6526 } 6527 #endif 6528 /* C hex */ 6529 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 6530 orntNew[0] = ornt[0]; 6531 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6532 orntNew[1] = 0; 6533 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6534 orntNew[2] = -1; 6535 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 6536 orntNew[3] = ornt[3]; 6537 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 6538 orntNew[4] = ornt[4]; 6539 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6540 orntNew[5] = -4; 6541 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 6542 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 6543 #if defined(PETSC_USE_DEBUG) 6544 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); 6545 for (p = 0; p < 6; ++p) { 6546 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); 6547 } 6548 #endif 6549 /* D hex */ 6550 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 6551 orntNew[0] = ornt[0]; 6552 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6553 orntNew[1] = 0; 6554 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 6555 orntNew[2] = ornt[2]; 6556 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6557 orntNew[3] = 0; 6558 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 6559 orntNew[4] = ornt[4]; 6560 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6561 orntNew[5] = -4; 6562 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 6563 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 6564 #if defined(PETSC_USE_DEBUG) 6565 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); 6566 for (p = 0; p < 6; ++p) { 6567 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); 6568 } 6569 #endif 6570 /* E hex */ 6571 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6572 orntNew[0] = -4; 6573 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 6574 orntNew[1] = ornt[1]; 6575 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 6576 orntNew[2] = ornt[2]; 6577 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6578 orntNew[3] = 0; 6579 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6580 orntNew[4] = -1; 6581 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 6582 orntNew[5] = ornt[5]; 6583 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 6584 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 6585 #if defined(PETSC_USE_DEBUG) 6586 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); 6587 for (p = 0; p < 6; ++p) { 6588 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); 6589 } 6590 #endif 6591 /* F hex */ 6592 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6593 orntNew[0] = -4; 6594 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 6595 orntNew[1] = ornt[1]; 6596 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 6597 orntNew[2] = ornt[2]; 6598 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6599 orntNew[3] = -1; 6600 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 6601 orntNew[4] = ornt[4]; 6602 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6603 orntNew[5] = 1; 6604 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 6605 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 6606 #if defined(PETSC_USE_DEBUG) 6607 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); 6608 for (p = 0; p < 6; ++p) { 6609 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); 6610 } 6611 #endif 6612 /* G hex */ 6613 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6614 orntNew[0] = -4; 6615 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 6616 orntNew[1] = ornt[1]; 6617 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6618 orntNew[2] = 0; 6619 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 6620 orntNew[3] = ornt[3]; 6621 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 6622 orntNew[4] = ornt[4]; 6623 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6624 orntNew[5] = -3; 6625 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 6626 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 6627 #if defined(PETSC_USE_DEBUG) 6628 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); 6629 for (p = 0; p < 6; ++p) { 6630 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6631 } 6632 #endif 6633 /* H hex */ 6634 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6635 orntNew[0] = -4; 6636 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 6637 orntNew[1] = ornt[1]; 6638 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6639 orntNew[2] = -1; 6640 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 6641 orntNew[3] = ornt[3]; 6642 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6643 orntNew[4] = 3; 6644 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 6645 orntNew[5] = ornt[5]; 6646 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 6647 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 6648 #if defined(PETSC_USE_DEBUG) 6649 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); 6650 for (p = 0; p < 6; ++p) { 6651 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6652 } 6653 #endif 6654 } 6655 /* Split faces have 4 edges and the same cells as the parent */ 6656 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6657 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 6658 for (f = fStart; f < fEnd; ++f) { 6659 for (r = 0; r < 4; ++r) { 6660 /* TODO: This can come from GetFaces_Internal() */ 6661 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}; 6662 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 6663 const PetscInt *cone, *ornt, *support; 6664 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 6665 6666 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6667 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6668 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 6669 orntNew[(r+3)%4] = ornt[(r+3)%4]; 6670 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 6671 orntNew[(r+0)%4] = ornt[r]; 6672 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 6673 orntNew[(r+1)%4] = 0; 6674 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 6675 orntNew[(r+2)%4] = -2; 6676 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6677 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6678 #if defined(PETSC_USE_DEBUG) 6679 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6680 for (p = 0; p < 4; ++p) { 6681 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); 6682 } 6683 #endif 6684 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6685 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6686 for (s = 0; s < supportSize; ++s) { 6687 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6688 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6689 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6690 for (c = 0; c < coneSize; ++c) { 6691 if (cone[c] == f) break; 6692 } 6693 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 6694 } 6695 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6696 #if defined(PETSC_USE_DEBUG) 6697 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6698 for (p = 0; p < supportSize; ++p) { 6699 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); 6700 } 6701 #endif 6702 } 6703 } 6704 /* Interior faces have 4 edges and 2 cells */ 6705 for (c = cStart; c < cEnd; ++c) { 6706 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}; 6707 const PetscInt *cone, *ornt; 6708 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 6709 6710 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6711 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6712 /* A-D face */ 6713 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 6714 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 6715 orntNew[0] = 0; 6716 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6717 orntNew[1] = 0; 6718 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6719 orntNew[2] = -2; 6720 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 6721 orntNew[3] = -2; 6722 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6723 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6724 #if defined(PETSC_USE_DEBUG) 6725 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6726 for (p = 0; p < 4; ++p) { 6727 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); 6728 } 6729 #endif 6730 /* C-D face */ 6731 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 6732 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 6733 orntNew[0] = 0; 6734 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6735 orntNew[1] = 0; 6736 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6737 orntNew[2] = -2; 6738 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 6739 orntNew[3] = -2; 6740 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6741 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6742 #if defined(PETSC_USE_DEBUG) 6743 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6744 for (p = 0; p < 4; ++p) { 6745 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); 6746 } 6747 #endif 6748 /* B-C face */ 6749 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 6750 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 6751 orntNew[0] = -2; 6752 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 6753 orntNew[1] = 0; 6754 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6755 orntNew[2] = 0; 6756 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6757 orntNew[3] = -2; 6758 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6759 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6760 #if defined(PETSC_USE_DEBUG) 6761 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6762 for (p = 0; p < 4; ++p) { 6763 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); 6764 } 6765 #endif 6766 /* A-B face */ 6767 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 6768 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 6769 orntNew[0] = -2; 6770 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 6771 orntNew[1] = 0; 6772 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6773 orntNew[2] = 0; 6774 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6775 orntNew[3] = -2; 6776 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6777 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6778 #if defined(PETSC_USE_DEBUG) 6779 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6780 for (p = 0; p < 4; ++p) { 6781 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); 6782 } 6783 #endif 6784 /* E-F face */ 6785 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 6786 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6787 orntNew[0] = -2; 6788 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 6789 orntNew[1] = -2; 6790 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 6791 orntNew[2] = 0; 6792 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6793 orntNew[3] = 0; 6794 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6795 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6796 #if defined(PETSC_USE_DEBUG) 6797 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6798 for (p = 0; p < 4; ++p) { 6799 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); 6800 } 6801 #endif 6802 /* F-G face */ 6803 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 6804 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6805 orntNew[0] = -2; 6806 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 6807 orntNew[1] = -2; 6808 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 6809 orntNew[2] = 0; 6810 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6811 orntNew[3] = 0; 6812 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6813 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6814 #if defined(PETSC_USE_DEBUG) 6815 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6816 for (p = 0; p < 4; ++p) { 6817 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); 6818 } 6819 #endif 6820 /* G-H face */ 6821 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 6822 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 6823 orntNew[0] = -2; 6824 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 6825 orntNew[1] = 0; 6826 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6827 orntNew[2] = 0; 6828 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6829 orntNew[3] = -2; 6830 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6831 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6832 #if defined(PETSC_USE_DEBUG) 6833 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6834 for (p = 0; p < 4; ++p) { 6835 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); 6836 } 6837 #endif 6838 /* E-H face */ 6839 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 6840 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6841 orntNew[0] = -2; 6842 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 6843 orntNew[1] = -2; 6844 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 6845 orntNew[2] = 0; 6846 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6847 orntNew[3] = 0; 6848 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6849 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6850 #if defined(PETSC_USE_DEBUG) 6851 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6852 for (p = 0; p < 4; ++p) { 6853 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6854 } 6855 #endif 6856 /* A-E face */ 6857 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 6858 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 6859 orntNew[0] = 0; 6860 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6861 orntNew[1] = 0; 6862 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6863 orntNew[2] = -2; 6864 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 6865 orntNew[3] = -2; 6866 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6867 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6868 #if defined(PETSC_USE_DEBUG) 6869 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6870 for (p = 0; p < 4; ++p) { 6871 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6872 } 6873 #endif 6874 /* D-F face */ 6875 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 6876 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 6877 orntNew[0] = -2; 6878 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 6879 orntNew[1] = 0; 6880 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6881 orntNew[2] = 0; 6882 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6883 orntNew[3] = -2; 6884 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6885 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6886 #if defined(PETSC_USE_DEBUG) 6887 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6888 for (p = 0; p < 4; ++p) { 6889 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6890 } 6891 #endif 6892 /* C-G face */ 6893 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 6894 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6895 orntNew[0] = -2; 6896 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 6897 orntNew[1] = -2; 6898 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 6899 orntNew[2] = 0; 6900 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6901 orntNew[3] = 0; 6902 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6903 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6904 #if defined(PETSC_USE_DEBUG) 6905 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6906 for (p = 0; p < 4; ++p) { 6907 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6908 } 6909 #endif 6910 /* B-H face */ 6911 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 6912 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6913 orntNew[0] = 0; 6914 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6915 orntNew[1] = -2; 6916 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 6917 orntNew[2] = -2; 6918 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 6919 orntNew[3] = 0; 6920 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6921 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6922 #if defined(PETSC_USE_DEBUG) 6923 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6924 for (p = 0; p < 4; ++p) { 6925 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6926 } 6927 #endif 6928 for (r = 0; r < 12; ++r) { 6929 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 6930 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 6931 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 6932 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6933 #if defined(PETSC_USE_DEBUG) 6934 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6935 for (p = 0; p < 2; ++p) { 6936 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); 6937 } 6938 #endif 6939 } 6940 } 6941 /* Split edges have 2 vertices and the same faces as the parent */ 6942 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6943 for (e = eStart; e < eEnd; ++e) { 6944 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6945 6946 for (r = 0; r < 2; ++r) { 6947 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6948 const PetscInt *cone, *ornt, *support; 6949 PetscInt coneNew[2], coneSize, c, supportSize, s; 6950 6951 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6952 coneNew[0] = vStartNew + (cone[0] - vStart); 6953 coneNew[1] = vStartNew + (cone[1] - vStart); 6954 coneNew[(r+1)%2] = newv; 6955 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6956 #if defined(PETSC_USE_DEBUG) 6957 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6958 for (p = 0; p < 2; ++p) { 6959 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); 6960 } 6961 #endif 6962 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6963 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6964 for (s = 0; s < supportSize; ++s) { 6965 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6966 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6967 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6968 for (c = 0; c < coneSize; ++c) { 6969 if (cone[c] == e) break; 6970 } 6971 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 6972 } 6973 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6974 #if defined(PETSC_USE_DEBUG) 6975 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6976 for (p = 0; p < supportSize; ++p) { 6977 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); 6978 } 6979 #endif 6980 } 6981 } 6982 /* Face edges have 2 vertices and 2+cells faces */ 6983 for (f = fStart; f < fEnd; ++f) { 6984 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}; 6985 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 6986 const PetscInt *cone, *coneCell, *orntCell, *support; 6987 PetscInt coneNew[2], coneSize, c, supportSize, s; 6988 6989 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6990 for (r = 0; r < 4; ++r) { 6991 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 6992 6993 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6994 coneNew[1] = newv; 6995 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6996 #if defined(PETSC_USE_DEBUG) 6997 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6998 for (p = 0; p < 2; ++p) { 6999 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); 7000 } 7001 #endif 7002 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7003 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7004 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7005 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7006 for (s = 0; s < supportSize; ++s) { 7007 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7008 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7009 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7010 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7011 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7012 } 7013 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7014 #if defined(PETSC_USE_DEBUG) 7015 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7016 for (p = 0; p < 2+supportSize; ++p) { 7017 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); 7018 } 7019 #endif 7020 } 7021 } 7022 /* Cell edges have 2 vertices and 4 faces */ 7023 for (c = cStart; c < cEnd; ++c) { 7024 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}; 7025 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7026 const PetscInt *cone; 7027 PetscInt coneNew[2], supportNew[4]; 7028 7029 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7030 for (r = 0; r < 6; ++r) { 7031 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7032 7033 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 7034 coneNew[1] = newv; 7035 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7036 #if defined(PETSC_USE_DEBUG) 7037 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7038 for (p = 0; p < 2; ++p) { 7039 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); 7040 } 7041 #endif 7042 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 7043 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7044 #if defined(PETSC_USE_DEBUG) 7045 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7046 for (p = 0; p < 4; ++p) { 7047 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); 7048 } 7049 #endif 7050 } 7051 } 7052 /* Old vertices have identical supports */ 7053 for (v = vStart; v < vEnd; ++v) { 7054 const PetscInt newp = vStartNew + (v - vStart); 7055 const PetscInt *support, *cone; 7056 PetscInt size, s; 7057 7058 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 7059 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 7060 for (s = 0; s < size; ++s) { 7061 PetscInt r = 0; 7062 7063 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7064 if (cone[1] == v) r = 1; 7065 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 7066 } 7067 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7068 #if defined(PETSC_USE_DEBUG) 7069 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7070 for (p = 0; p < size; ++p) { 7071 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); 7072 } 7073 #endif 7074 } 7075 /* Edge vertices have 2 + faces supports */ 7076 for (e = eStart; e < eEnd; ++e) { 7077 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 7078 const PetscInt *cone, *support; 7079 PetscInt size, s; 7080 7081 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 7082 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7083 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 7084 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 7085 for (s = 0; s < size; ++s) { 7086 PetscInt r; 7087 7088 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7089 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 7090 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 7091 } 7092 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7093 #if defined(PETSC_USE_DEBUG) 7094 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7095 for (p = 0; p < 2+size; ++p) { 7096 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); 7097 } 7098 #endif 7099 } 7100 /* Face vertices have 4 + cells supports */ 7101 for (f = fStart; f < fEnd; ++f) { 7102 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7103 const PetscInt *cone, *support; 7104 PetscInt size, s; 7105 7106 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7107 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7108 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7109 for (s = 0; s < size; ++s) { 7110 PetscInt r; 7111 7112 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7113 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 7114 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 7115 } 7116 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7117 #if defined(PETSC_USE_DEBUG) 7118 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7119 for (p = 0; p < 4+size; ++p) { 7120 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); 7121 } 7122 #endif 7123 } 7124 /* Cell vertices have 6 supports */ 7125 for (c = cStart; c < cEnd; ++c) { 7126 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7127 PetscInt supportNew[6]; 7128 7129 for (r = 0; r < 6; ++r) { 7130 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7131 } 7132 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7133 } 7134 ierr = PetscFree(supportRef);CHKERRQ(ierr); 7135 break; 7136 case REFINER_HYBRID_HEX_3D: 7137 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 7138 /* 7139 Bottom (viewed from top) Top 7140 1---------2---------2 7---------2---------6 7141 | | | | | | 7142 | B 2 C | | H 2 G | 7143 | | | | | | 7144 3----3----0----1----1 3----3----0----1----1 7145 | | | | | | 7146 | A 0 D | | E 0 F | 7147 | | | | | | 7148 0---------0---------3 4---------0---------5 7149 */ 7150 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 7151 for (c = cStart; c < cMax; ++c) { 7152 const PetscInt newp = (c - cStart)*8; 7153 const PetscInt *cone, *ornt; 7154 PetscInt coneNew[6], orntNew[6]; 7155 7156 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7157 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7158 /* A hex */ 7159 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 7160 orntNew[0] = ornt[0]; 7161 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7162 orntNew[1] = 0; 7163 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 7164 orntNew[2] = ornt[2]; 7165 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7166 orntNew[3] = 0; 7167 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7168 orntNew[4] = 0; 7169 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 7170 orntNew[5] = ornt[5]; 7171 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 7172 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 7173 #if defined(PETSC_USE_DEBUG) 7174 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); 7175 for (p = 0; p < 6; ++p) { 7176 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); 7177 } 7178 #endif 7179 /* B hex */ 7180 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 7181 orntNew[0] = ornt[0]; 7182 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7183 orntNew[1] = 0; 7184 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7185 orntNew[2] = -1; 7186 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 7187 orntNew[3] = ornt[3]; 7188 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7189 orntNew[4] = 0; 7190 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 7191 orntNew[5] = ornt[5]; 7192 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 7193 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 7194 #if defined(PETSC_USE_DEBUG) 7195 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); 7196 for (p = 0; p < 6; ++p) { 7197 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); 7198 } 7199 #endif 7200 /* C hex */ 7201 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 7202 orntNew[0] = ornt[0]; 7203 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7204 orntNew[1] = 0; 7205 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7206 orntNew[2] = -1; 7207 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 7208 orntNew[3] = ornt[3]; 7209 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 7210 orntNew[4] = ornt[4]; 7211 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7212 orntNew[5] = -4; 7213 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 7214 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 7215 #if defined(PETSC_USE_DEBUG) 7216 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); 7217 for (p = 0; p < 6; ++p) { 7218 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); 7219 } 7220 #endif 7221 /* D hex */ 7222 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 7223 orntNew[0] = ornt[0]; 7224 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7225 orntNew[1] = 0; 7226 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 7227 orntNew[2] = ornt[2]; 7228 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7229 orntNew[3] = 0; 7230 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 7231 orntNew[4] = ornt[4]; 7232 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7233 orntNew[5] = -4; 7234 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 7235 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 7236 #if defined(PETSC_USE_DEBUG) 7237 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); 7238 for (p = 0; p < 6; ++p) { 7239 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); 7240 } 7241 #endif 7242 /* E hex */ 7243 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7244 orntNew[0] = -4; 7245 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 7246 orntNew[1] = ornt[1]; 7247 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 7248 orntNew[2] = ornt[2]; 7249 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7250 orntNew[3] = 0; 7251 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7252 orntNew[4] = -1; 7253 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 7254 orntNew[5] = ornt[5]; 7255 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 7256 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 7257 #if defined(PETSC_USE_DEBUG) 7258 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); 7259 for (p = 0; p < 6; ++p) { 7260 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); 7261 } 7262 #endif 7263 /* F hex */ 7264 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7265 orntNew[0] = -4; 7266 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 7267 orntNew[1] = ornt[1]; 7268 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 7269 orntNew[2] = ornt[2]; 7270 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7271 orntNew[3] = -1; 7272 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 7273 orntNew[4] = ornt[4]; 7274 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7275 orntNew[5] = 1; 7276 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 7277 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 7278 #if defined(PETSC_USE_DEBUG) 7279 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); 7280 for (p = 0; p < 6; ++p) { 7281 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); 7282 } 7283 #endif 7284 /* G hex */ 7285 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7286 orntNew[0] = -4; 7287 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 7288 orntNew[1] = ornt[1]; 7289 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7290 orntNew[2] = 0; 7291 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 7292 orntNew[3] = ornt[3]; 7293 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 7294 orntNew[4] = ornt[4]; 7295 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7296 orntNew[5] = -3; 7297 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 7298 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 7299 #if defined(PETSC_USE_DEBUG) 7300 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); 7301 for (p = 0; p < 6; ++p) { 7302 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7303 } 7304 #endif 7305 /* H hex */ 7306 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7307 orntNew[0] = -4; 7308 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 7309 orntNew[1] = ornt[1]; 7310 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7311 orntNew[2] = -1; 7312 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 7313 orntNew[3] = ornt[3]; 7314 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7315 orntNew[4] = 3; 7316 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 7317 orntNew[5] = ornt[5]; 7318 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 7319 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 7320 #if defined(PETSC_USE_DEBUG) 7321 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); 7322 for (p = 0; p < 6; ++p) { 7323 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7324 } 7325 #endif 7326 } 7327 /* Hybrid cells have 6 faces: Front, Back, Sides */ 7328 /* 7329 3---------2---------2 7330 | | | 7331 | D 2 C | 7332 | | | 7333 3----3----0----1----1 7334 | | | 7335 | A 0 B | 7336 | | | 7337 0---------0---------1 7338 */ 7339 for (c = cMax; c < cEnd; ++c) { 7340 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 7341 const PetscInt *cone, *ornt, *fornt; 7342 PetscInt coneNew[6], orntNew[6], o, of, i; 7343 7344 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7345 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7346 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 7347 o = ornt[0] < 0 ? -1 : 1; 7348 for (r = 0; r < 4; ++r) { 7349 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 7350 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 7351 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 7352 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]); 7353 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 7354 orntNew[0] = ornt[0]; 7355 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 7356 orntNew[1] = ornt[0]; 7357 of = fornt[edgeA] < 0 ? -1 : 1; 7358 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 7359 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 7360 orntNew[i] = ornt[edgeA]; 7361 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 7362 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 7363 orntNew[i] = 0; 7364 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 7365 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 7366 orntNew[i] = -2; 7367 of = fornt[edgeB] < 0 ? -1 : 1; 7368 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 7369 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 7370 orntNew[i] = ornt[edgeB]; 7371 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7372 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7373 #if defined(PETSC_USE_DEBUG) 7374 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); 7375 for (p = 0; p < 2; ++p) { 7376 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); 7377 } 7378 for (p = 2; p < 6; ++p) { 7379 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); 7380 } 7381 #endif 7382 } 7383 } 7384 /* Interior split faces have 4 edges and the same cells as the parent */ 7385 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7386 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 7387 for (f = fStart; f < fMax; ++f) { 7388 for (r = 0; r < 4; ++r) { 7389 /* TODO: This can come from GetFaces_Internal() */ 7390 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}; 7391 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 7392 const PetscInt *cone, *ornt, *support; 7393 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 7394 7395 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7396 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7397 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 7398 orntNew[(r+3)%4] = ornt[(r+3)%4]; 7399 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 7400 orntNew[(r+0)%4] = ornt[r]; 7401 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7402 orntNew[(r+1)%4] = 0; 7403 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 7404 orntNew[(r+2)%4] = -2; 7405 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7406 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7407 #if defined(PETSC_USE_DEBUG) 7408 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7409 for (p = 0; p < 4; ++p) { 7410 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); 7411 } 7412 #endif 7413 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7414 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7415 for (s = 0; s < supportSize; ++s) { 7416 PetscInt subf; 7417 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7418 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7419 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7420 for (c = 0; c < coneSize; ++c) { 7421 if (cone[c] == f) break; 7422 } 7423 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 7424 if (support[s] < cMax) { 7425 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 7426 } else { 7427 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 7428 } 7429 } 7430 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7431 #if defined(PETSC_USE_DEBUG) 7432 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7433 for (p = 0; p < supportSize; ++p) { 7434 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); 7435 } 7436 #endif 7437 } 7438 } 7439 /* Interior cell faces have 4 edges and 2 cells */ 7440 for (c = cStart; c < cMax; ++c) { 7441 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}; 7442 const PetscInt *cone, *ornt; 7443 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 7444 7445 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7446 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7447 /* A-D face */ 7448 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 7449 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 7450 orntNew[0] = 0; 7451 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7452 orntNew[1] = 0; 7453 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7454 orntNew[2] = -2; 7455 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 7456 orntNew[3] = -2; 7457 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7458 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7459 #if defined(PETSC_USE_DEBUG) 7460 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7461 for (p = 0; p < 4; ++p) { 7462 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); 7463 } 7464 #endif 7465 /* C-D face */ 7466 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 7467 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 7468 orntNew[0] = 0; 7469 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7470 orntNew[1] = 0; 7471 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7472 orntNew[2] = -2; 7473 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 7474 orntNew[3] = -2; 7475 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7476 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7477 #if defined(PETSC_USE_DEBUG) 7478 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7479 for (p = 0; p < 4; ++p) { 7480 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); 7481 } 7482 #endif 7483 /* B-C face */ 7484 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 7485 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 7486 orntNew[0] = -2; 7487 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 7488 orntNew[1] = 0; 7489 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7490 orntNew[2] = 0; 7491 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7492 orntNew[3] = -2; 7493 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7494 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7495 #if defined(PETSC_USE_DEBUG) 7496 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7497 for (p = 0; p < 4; ++p) { 7498 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); 7499 } 7500 #endif 7501 /* A-B face */ 7502 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 7503 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 7504 orntNew[0] = -2; 7505 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 7506 orntNew[1] = 0; 7507 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7508 orntNew[2] = 0; 7509 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7510 orntNew[3] = -2; 7511 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7512 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7513 #if defined(PETSC_USE_DEBUG) 7514 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7515 for (p = 0; p < 4; ++p) { 7516 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); 7517 } 7518 #endif 7519 /* E-F face */ 7520 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 7521 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7522 orntNew[0] = -2; 7523 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 7524 orntNew[1] = -2; 7525 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 7526 orntNew[2] = 0; 7527 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7528 orntNew[3] = 0; 7529 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7530 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7531 #if defined(PETSC_USE_DEBUG) 7532 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7533 for (p = 0; p < 4; ++p) { 7534 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); 7535 } 7536 #endif 7537 /* F-G face */ 7538 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 7539 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7540 orntNew[0] = -2; 7541 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 7542 orntNew[1] = -2; 7543 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 7544 orntNew[2] = 0; 7545 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7546 orntNew[3] = 0; 7547 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7548 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7549 #if defined(PETSC_USE_DEBUG) 7550 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7551 for (p = 0; p < 4; ++p) { 7552 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); 7553 } 7554 #endif 7555 /* G-H face */ 7556 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 7557 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 7558 orntNew[0] = -2; 7559 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 7560 orntNew[1] = 0; 7561 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7562 orntNew[2] = 0; 7563 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7564 orntNew[3] = -2; 7565 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7566 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7567 #if defined(PETSC_USE_DEBUG) 7568 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7569 for (p = 0; p < 4; ++p) { 7570 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); 7571 } 7572 #endif 7573 /* E-H face */ 7574 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 7575 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7576 orntNew[0] = -2; 7577 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 7578 orntNew[1] = -2; 7579 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 7580 orntNew[2] = 0; 7581 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7582 orntNew[3] = 0; 7583 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7584 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7585 #if defined(PETSC_USE_DEBUG) 7586 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7587 for (p = 0; p < 4; ++p) { 7588 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7589 } 7590 #endif 7591 /* A-E face */ 7592 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 7593 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 7594 orntNew[0] = 0; 7595 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7596 orntNew[1] = 0; 7597 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7598 orntNew[2] = -2; 7599 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 7600 orntNew[3] = -2; 7601 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7602 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7603 #if defined(PETSC_USE_DEBUG) 7604 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7605 for (p = 0; p < 4; ++p) { 7606 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7607 } 7608 #endif 7609 /* D-F face */ 7610 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 7611 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 7612 orntNew[0] = -2; 7613 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 7614 orntNew[1] = 0; 7615 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7616 orntNew[2] = 0; 7617 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7618 orntNew[3] = -2; 7619 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7620 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7621 #if defined(PETSC_USE_DEBUG) 7622 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7623 for (p = 0; p < 4; ++p) { 7624 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7625 } 7626 #endif 7627 /* C-G face */ 7628 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 7629 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7630 orntNew[0] = -2; 7631 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7632 orntNew[1] = -2; 7633 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7634 orntNew[2] = 0; 7635 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7636 orntNew[3] = 0; 7637 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7638 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7639 #if defined(PETSC_USE_DEBUG) 7640 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7641 for (p = 0; p < 4; ++p) { 7642 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7643 } 7644 #endif 7645 /* B-H face */ 7646 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 7647 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7648 orntNew[0] = 0; 7649 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7650 orntNew[1] = -2; 7651 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7652 orntNew[2] = -2; 7653 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7654 orntNew[3] = 0; 7655 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7656 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7657 #if defined(PETSC_USE_DEBUG) 7658 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7659 for (p = 0; p < 4; ++p) { 7660 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7661 } 7662 #endif 7663 for (r = 0; r < 12; ++r) { 7664 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 7665 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7666 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7667 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7668 #if defined(PETSC_USE_DEBUG) 7669 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7670 for (p = 0; p < 2; ++p) { 7671 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); 7672 } 7673 #endif 7674 } 7675 } 7676 /* Hybrid split faces have 4 edges and same cells */ 7677 for (f = fMax; f < fEnd; ++f) { 7678 const PetscInt *cone, *ornt, *support; 7679 PetscInt coneNew[4], orntNew[4]; 7680 PetscInt supportNew[2], size, s, c; 7681 7682 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7683 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7684 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7685 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7686 for (r = 0; r < 2; ++r) { 7687 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 7688 7689 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 7690 orntNew[0] = ornt[0]; 7691 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 7692 orntNew[1] = ornt[1]; 7693 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 7694 orntNew[2+r] = 0; 7695 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 7696 orntNew[3-r] = 0; 7697 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7698 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7699 #if defined(PETSC_USE_DEBUG) 7700 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7701 for (p = 0; p < 2; ++p) { 7702 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); 7703 } 7704 for (p = 2; p < 4; ++p) { 7705 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); 7706 } 7707 #endif 7708 for (s = 0; s < size; ++s) { 7709 const PetscInt *coneCell, *orntCell, *fornt; 7710 PetscInt o, of; 7711 7712 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7713 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7714 o = orntCell[0] < 0 ? -1 : 1; 7715 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 7716 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 7717 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 7718 of = fornt[c-2] < 0 ? -1 : 1; 7719 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 7720 } 7721 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7722 #if defined(PETSC_USE_DEBUG) 7723 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7724 for (p = 0; p < size; ++p) { 7725 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); 7726 } 7727 #endif 7728 } 7729 } 7730 /* Hybrid cell faces have 4 edges and 2 cells */ 7731 for (c = cMax; c < cEnd; ++c) { 7732 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 7733 const PetscInt *cone, *ornt; 7734 PetscInt coneNew[4], orntNew[4]; 7735 PetscInt supportNew[2]; 7736 7737 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7738 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7739 for (r = 0; r < 4; ++r) { 7740 #if 0 7741 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 7742 orntNew[0] = 0; 7743 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 7744 orntNew[1] = 0; 7745 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 7746 orntNew[2] = 0; 7747 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7748 orntNew[3] = 0; 7749 #else 7750 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 7751 orntNew[0] = 0; 7752 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 7753 orntNew[1] = 0; 7754 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 7755 orntNew[2] = 0; 7756 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7757 orntNew[3] = 0; 7758 #endif 7759 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7760 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7761 #if defined(PETSC_USE_DEBUG) 7762 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); 7763 for (p = 0; p < 2; ++p) { 7764 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); 7765 } 7766 for (p = 2; p < 4; ++p) { 7767 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); 7768 } 7769 #endif 7770 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 7771 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 7772 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 7773 #if defined(PETSC_USE_DEBUG) 7774 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); 7775 for (p = 0; p < 2; ++p) { 7776 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); 7777 } 7778 #endif 7779 } 7780 } 7781 /* Interior split edges have 2 vertices and the same faces as the parent */ 7782 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7783 for (e = eStart; e < eMax; ++e) { 7784 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7785 7786 for (r = 0; r < 2; ++r) { 7787 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7788 const PetscInt *cone, *ornt, *support; 7789 PetscInt coneNew[2], coneSize, c, supportSize, s; 7790 7791 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7792 coneNew[0] = vStartNew + (cone[0] - vStart); 7793 coneNew[1] = vStartNew + (cone[1] - vStart); 7794 coneNew[(r+1)%2] = newv; 7795 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7796 #if defined(PETSC_USE_DEBUG) 7797 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7798 for (p = 0; p < 2; ++p) { 7799 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); 7800 } 7801 #endif 7802 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7803 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7804 for (s = 0; s < supportSize; ++s) { 7805 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7806 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7807 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7808 for (c = 0; c < coneSize; ++c) { 7809 if (cone[c] == e) break; 7810 } 7811 if (support[s] < fMax) { 7812 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 7813 } else { 7814 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 7815 } 7816 } 7817 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7818 #if defined(PETSC_USE_DEBUG) 7819 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7820 for (p = 0; p < supportSize; ++p) { 7821 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); 7822 } 7823 #endif 7824 } 7825 } 7826 /* Interior face edges have 2 vertices and 2+cells faces */ 7827 for (f = fStart; f < fMax; ++f) { 7828 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}; 7829 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 7830 const PetscInt *cone, *coneCell, *orntCell, *support; 7831 PetscInt coneNew[2], coneSize, c, supportSize, s; 7832 7833 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7834 for (r = 0; r < 4; ++r) { 7835 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7836 7837 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7838 coneNew[1] = newv; 7839 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7840 #if defined(PETSC_USE_DEBUG) 7841 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7842 for (p = 0; p < 2; ++p) { 7843 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); 7844 } 7845 #endif 7846 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7847 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7848 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7849 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7850 for (s = 0; s < supportSize; ++s) { 7851 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7852 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7853 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7854 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7855 if (support[s] < cMax) { 7856 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7857 } else { 7858 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 7859 } 7860 } 7861 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7862 #if defined(PETSC_USE_DEBUG) 7863 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7864 for (p = 0; p < 2+supportSize; ++p) { 7865 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); 7866 } 7867 #endif 7868 } 7869 } 7870 /* Interior cell edges have 2 vertices and 4 faces */ 7871 for (c = cStart; c < cMax; ++c) { 7872 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}; 7873 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 7874 const PetscInt *cone; 7875 PetscInt coneNew[2], supportNew[4]; 7876 7877 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7878 for (r = 0; r < 6; ++r) { 7879 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 7880 7881 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 7882 coneNew[1] = newv; 7883 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7884 #if defined(PETSC_USE_DEBUG) 7885 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7886 for (p = 0; p < 2; ++p) { 7887 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); 7888 } 7889 #endif 7890 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 7891 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7892 #if defined(PETSC_USE_DEBUG) 7893 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7894 for (p = 0; p < 4; ++p) { 7895 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); 7896 } 7897 #endif 7898 } 7899 } 7900 /* Hybrid edges have two vertices and the same faces */ 7901 for (e = eMax; e < eEnd; ++e) { 7902 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 7903 const PetscInt *cone, *support, *fcone; 7904 PetscInt coneNew[2], size, fsize, s; 7905 7906 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7907 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 7908 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7909 coneNew[0] = vStartNew + (cone[0] - vStart); 7910 coneNew[1] = vStartNew + (cone[1] - vStart); 7911 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7912 #if defined(PETSC_USE_DEBUG) 7913 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7914 for (p = 0; p < 2; ++p) { 7915 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); 7916 } 7917 #endif 7918 for (s = 0; s < size; ++s) { 7919 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 7920 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 7921 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 7922 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 7923 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 7924 } 7925 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7926 #if defined(PETSC_USE_DEBUG) 7927 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7928 for (p = 0; p < size; ++p) { 7929 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); 7930 } 7931 #endif 7932 } 7933 /* Hybrid face edges have 2 vertices and 2+cells faces */ 7934 for (f = fMax; f < fEnd; ++f) { 7935 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 7936 const PetscInt *cone, *support, *ccone, *cornt; 7937 PetscInt coneNew[2], size, csize, s; 7938 7939 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7940 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7941 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7942 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 7943 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 7944 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7945 #if defined(PETSC_USE_DEBUG) 7946 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7947 for (p = 0; p < 2; ++p) { 7948 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); 7949 } 7950 #endif 7951 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 7952 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 7953 for (s = 0; s < size; ++s) { 7954 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 7955 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 7956 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 7957 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 7958 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]); 7959 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 7960 } 7961 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7962 #if defined(PETSC_USE_DEBUG) 7963 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7964 for (p = 0; p < 2+size; ++p) { 7965 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); 7966 } 7967 #endif 7968 } 7969 /* Hybrid cell edges have 2 vertices and 4 faces */ 7970 for (c = cMax; c < cEnd; ++c) { 7971 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7972 const PetscInt *cone, *support; 7973 PetscInt coneNew[2], size; 7974 7975 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7976 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 7977 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 7978 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 7979 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 7980 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7981 #if defined(PETSC_USE_DEBUG) 7982 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7983 for (p = 0; p < 2; ++p) { 7984 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); 7985 } 7986 #endif 7987 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 7988 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 7989 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 7990 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 7991 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7992 #if defined(PETSC_USE_DEBUG) 7993 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7994 for (p = 0; p < 4; ++p) { 7995 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); 7996 } 7997 #endif 7998 } 7999 /* Interior vertices have identical supports */ 8000 for (v = vStart; v < vEnd; ++v) { 8001 const PetscInt newp = vStartNew + (v - vStart); 8002 const PetscInt *support, *cone; 8003 PetscInt size, s; 8004 8005 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 8006 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 8007 for (s = 0; s < size; ++s) { 8008 PetscInt r = 0; 8009 8010 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8011 if (cone[1] == v) r = 1; 8012 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 8013 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 8014 } 8015 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8016 #if defined(PETSC_USE_DEBUG) 8017 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8018 for (p = 0; p < size; ++p) { 8019 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); 8020 } 8021 #endif 8022 } 8023 /* Interior edge vertices have 2 + faces supports */ 8024 for (e = eStart; e < eMax; ++e) { 8025 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 8026 const PetscInt *cone, *support; 8027 PetscInt size, s; 8028 8029 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8030 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8031 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 8032 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 8033 for (s = 0; s < size; ++s) { 8034 PetscInt r; 8035 8036 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8037 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 8038 if (support[s] < fMax) { 8039 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 8040 } else { 8041 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 8042 } 8043 } 8044 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8045 #if defined(PETSC_USE_DEBUG) 8046 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8047 for (p = 0; p < 2+size; ++p) { 8048 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); 8049 } 8050 #endif 8051 } 8052 /* Interior face vertices have 4 + cells supports */ 8053 for (f = fStart; f < fMax; ++f) { 8054 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8055 const PetscInt *cone, *support; 8056 PetscInt size, s; 8057 8058 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8059 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8060 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 8061 for (s = 0; s < size; ++s) { 8062 PetscInt r; 8063 8064 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8065 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 8066 if (support[s] < cMax) { 8067 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 8068 } else { 8069 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 8070 } 8071 } 8072 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8073 #if defined(PETSC_USE_DEBUG) 8074 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8075 for (p = 0; p < 4+size; ++p) { 8076 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); 8077 } 8078 #endif 8079 } 8080 /* Cell vertices have 6 supports */ 8081 for (c = cStart; c < cMax; ++c) { 8082 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 8083 PetscInt supportNew[6]; 8084 8085 for (r = 0; r < 6; ++r) { 8086 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8087 } 8088 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8089 } 8090 ierr = PetscFree(supportRef);CHKERRQ(ierr); 8091 break; 8092 default: 8093 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8094 } 8095 PetscFunctionReturn(0); 8096 } 8097 8098 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8099 { 8100 PetscSection coordSection, coordSectionNew; 8101 Vec coordinates, coordinatesNew; 8102 PetscScalar *coords, *coordsNew; 8103 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 8104 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax; 8105 PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 8106 PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL; 8107 VecType vtype; 8108 PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE; 8109 const PetscReal *maxCell, *L; 8110 const DMBoundaryType *bd; 8111 PetscErrorCode ierr; 8112 8113 PetscFunctionBegin; 8114 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8115 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8116 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8117 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8118 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8119 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8120 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 8121 if (cMax < 0) cMax = cEnd; 8122 if (fMax < 0) fMax = fEnd; 8123 if (eMax < 0) eMax = eEnd; 8124 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr); 8125 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr); 8126 ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 8127 /* Determine if we need to localize coordinates when generating them */ 8128 if (isperiodic && !maxCell) { 8129 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 8130 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 8131 } 8132 if (isperiodic) { 8133 ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");CHKERRQ(ierr); 8134 ierr = PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);CHKERRQ(ierr); 8135 ierr = PetscOptionsEnd();CHKERRQ(ierr); 8136 if (localize) { 8137 ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 8138 } 8139 } 8140 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 8141 8142 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 8143 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 8144 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 8145 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 8146 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 8147 8148 if (localize) { 8149 PetscInt p, r, newp, *pi; 8150 8151 /* New coordinates will be already localized on the cell */ 8152 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 8153 8154 /* We need the parentId to properly localize coordinates */ 8155 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 8156 switch (refiner) { 8157 case REFINER_NOOP: 8158 break; 8159 case REFINER_SIMPLEX_1D: 8160 for (p = cStart; p < cEnd; ++p) { 8161 for (r = 0; r < 2; ++r) { 8162 newp = (p - cStart)*2 + r; 8163 pi[newp] = p; 8164 } 8165 } 8166 break; 8167 case REFINER_SIMPLEX_2D: 8168 for (p = cStart; p < cEnd; ++p) { 8169 for (r = 0; r < 4; ++r) { 8170 newp = (p - cStart)*4 + r; 8171 pi[newp] = p; 8172 } 8173 } 8174 break; 8175 case REFINER_HEX_2D: 8176 for (p = cStart; p < cEnd; ++p) { 8177 for (r = 0; r < 4; ++r) { 8178 newp = (p - cStart)*4 + r; 8179 pi[newp] = p; 8180 } 8181 } 8182 break; 8183 case REFINER_SIMPLEX_TO_HEX_2D: 8184 for (p = cStart; p < cEnd; ++p) { 8185 for (r = 0; r < 3; ++r) { 8186 newp = (p - cStart)*3 + r; 8187 pi[newp] = p; 8188 } 8189 } 8190 break; 8191 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8192 for (p = cStart; p < cMax; ++p) { 8193 for (r = 0; r < 3; ++r) { 8194 newp = (p - cStart)*3 + r; 8195 pi[newp] = p; 8196 } 8197 } 8198 for (p = cMax; p < cEnd; ++p) { 8199 for (r = 0; r < 4; ++r) { 8200 newp = (cMax - cStart)*3 + (p - cMax)*4 + r; 8201 pi[newp] = p; 8202 } 8203 } 8204 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8205 cMax = cEnd; 8206 eMax = eEnd; 8207 break; 8208 case REFINER_HYBRID_SIMPLEX_2D: 8209 for (p = cStart; p < cMax; ++p) { 8210 for (r = 0; r < 4; ++r) { 8211 newp = (p - cStart)*4 + r; 8212 pi[newp] = p; 8213 } 8214 } 8215 for (p = cMax; p < cEnd; ++p) { 8216 for (r = 0; r < 2; ++r) { 8217 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8218 pi[newp] = p; 8219 } 8220 } 8221 break; 8222 case REFINER_HYBRID_HEX_2D: 8223 for (p = cStart; p < cMax; ++p) { 8224 for (r = 0; r < 4; ++r) { 8225 newp = (p - cStart)*4 + r; 8226 pi[newp] = p; 8227 } 8228 } 8229 for (p = cMax; p < cEnd; ++p) { 8230 for (r = 0; r < 2; ++r) { 8231 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8232 pi[newp] = p; 8233 } 8234 } 8235 break; 8236 case REFINER_SIMPLEX_3D: 8237 for (p = cStart; p < cEnd; ++p) { 8238 for (r = 0; r < 8; ++r) { 8239 newp = (p - cStart)*8 + r; 8240 pi[newp] = p; 8241 } 8242 } 8243 break; 8244 case REFINER_HYBRID_SIMPLEX_3D: 8245 for (p = cStart; p < cMax; ++p) { 8246 for (r = 0; r < 8; ++r) { 8247 newp = (p - cStart)*8 + r; 8248 pi[newp] = p; 8249 } 8250 } 8251 for (p = cMax; p < cEnd; ++p) { 8252 for (r = 0; r < 4; ++r) { 8253 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8254 pi[newp] = p; 8255 } 8256 } 8257 break; 8258 case REFINER_SIMPLEX_TO_HEX_3D: 8259 for (p = cStart; p < cEnd; ++p) { 8260 for (r = 0; r < 4; ++r) { 8261 newp = (p - cStart)*4 + r; 8262 pi[newp] = p; 8263 } 8264 } 8265 break; 8266 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8267 for (p = cStart; p < cMax; ++p) { 8268 for (r = 0; r < 4; ++r) { 8269 newp = (p - cStart)*4 + r; 8270 pi[newp] = p; 8271 } 8272 } 8273 for (p = cMax; p < cEnd; ++p) { 8274 for (r = 0; r < 3; ++r) { 8275 newp = (cMax - cStart)*4 + (p - cMax)*3 + r; 8276 pi[newp] = p; 8277 } 8278 } 8279 break; 8280 case REFINER_HEX_3D: 8281 for (p = cStart; p < cEnd; ++p) { 8282 for (r = 0; r < 8; ++r) { 8283 newp = (p - cStart)*8 + r; 8284 pi[newp] = p; 8285 } 8286 } 8287 break; 8288 case REFINER_HYBRID_HEX_3D: 8289 for (p = cStart; p < cMax; ++p) { 8290 for (r = 0; r < 8; ++r) { 8291 newp = (p - cStart)*8 + r; 8292 pi[newp] = p; 8293 } 8294 } 8295 for (p = cMax; p < cEnd; ++p) { 8296 for (r = 0; r < 4; ++r) { 8297 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8298 pi[newp] = p; 8299 } 8300 } 8301 break; 8302 default: 8303 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8304 } 8305 parentId = pi; 8306 } else { 8307 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8308 if (REFINER_HYBRID_SIMPLEX_TO_HEX_2D == refiner) { cMax = cEnd; eMax = eEnd; } 8309 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 8310 } 8311 8312 /* All vertices have the spaceDim coordinates */ 8313 if (localize) { 8314 PetscInt c; 8315 8316 for (c = cStartNew; c < cEndNew; ++c) { 8317 PetscInt *cone = NULL; 8318 PetscInt closureSize, coneSize = 0, p, pdof; 8319 8320 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 8321 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 8322 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8323 for (p = 0; p < closureSize*2; p += 2) { 8324 const PetscInt point = cone[p]; 8325 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 8326 } 8327 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8328 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 8329 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 8330 } 8331 } 8332 } 8333 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 8334 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 8335 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 8336 } 8337 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 8338 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 8339 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8340 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 8341 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 8342 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 8343 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 8344 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 8345 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 8346 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 8347 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 8348 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 8349 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8350 8351 switch (refiner) { 8352 case REFINER_NOOP: break; 8353 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8354 case REFINER_SIMPLEX_TO_HEX_3D: 8355 case REFINER_HEX_3D: 8356 case REFINER_HYBRID_HEX_3D: 8357 /* Face vertices have the average of corner coordinates */ 8358 for (f = fStart; f < fMax; ++f) { 8359 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8360 PetscInt *cone = NULL; 8361 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 8362 8363 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8364 for (p = 0; p < closureSize*2; p += 2) { 8365 const PetscInt point = cone[p]; 8366 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8367 } 8368 if (localize) { 8369 const PetscInt *support = NULL; 8370 PetscInt *rStar = NULL; 8371 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 8372 PetscBool cellfound = PETSC_FALSE; 8373 8374 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8375 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 8376 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 8377 /* Compute average of coordinates for each cell sharing the face */ 8378 for (s = 0; s < supportSize; ++s) { 8379 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 8380 PetscInt *cellCone = NULL; 8381 PetscInt cellClosureSize, cellConeSize = 0, cdof; 8382 const PetscInt cell = support[s]; 8383 PetscBool copyoff = PETSC_FALSE; 8384 8385 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8386 for (p = 0; p < cellClosureSize*2; p += 2) { 8387 const PetscInt point = cellCone[p]; 8388 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 8389 } 8390 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8391 if (!cdof) { /* the parent cell does not have localized coordinates */ 8392 cellfound = PETSC_TRUE; 8393 for (v = 0; v < coneSize; ++v) { 8394 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8395 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 8396 } 8397 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8398 } else { 8399 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8400 for (p = 0; p < coneSize; ++p) { 8401 const PetscInt tv = cone[p]; 8402 PetscInt cv, voff; 8403 PetscBool locv = PETSC_TRUE; 8404 8405 for (cv = 0; cv < cellConeSize; ++cv) { 8406 if (cellCone[cv] == tv) { 8407 ccoff[p] = spaceDim*cv + coff; 8408 break; 8409 } 8410 } 8411 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D",tv); 8412 8413 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 8414 for (d = 0; d < spaceDim; ++d) { 8415 coordsNewAux[d] += coords[ccoff[p]+d]; 8416 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 8417 } 8418 if (locv && !cellfound) { 8419 cellfound = PETSC_TRUE; 8420 copyoff = PETSC_TRUE; 8421 } 8422 } 8423 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8424 8425 /* Found a valid face for the "vertex" part of the Section (physical space) 8426 i.e., a face that has at least one corner in the physical space */ 8427 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 8428 } 8429 8430 /* Localize new coordinates on each refined cell */ 8431 for (v = 0; v < rStarSize*2; v += 2) { 8432 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 8433 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 8434 const PetscInt rcell = rStar[v]; 8435 8436 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8437 if (!rcdof) continue; 8438 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 8439 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8440 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8441 if (rcone[p] == newv) { 8442 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 8443 break; 8444 } 8445 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8446 } 8447 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8448 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8449 } 8450 } 8451 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8452 } 8453 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8454 if (!cellfound) { 8455 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 8456 needcoords = PETSC_TRUE; 8457 coneSize = 0; 8458 } 8459 } else { 8460 for (v = 0; v < coneSize; ++v) { 8461 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8462 } 8463 } 8464 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8465 if (coneSize) { 8466 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8467 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8468 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8469 } else { 8470 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8471 } 8472 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8473 } 8474 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8475 case REFINER_SIMPLEX_TO_HEX_2D: 8476 case REFINER_HEX_2D: 8477 case REFINER_HYBRID_HEX_2D: 8478 case REFINER_SIMPLEX_1D: 8479 /* Cell vertices have the average of corner coordinates */ 8480 for (c = cStart; c < cMax; ++c) { 8481 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 8482 PetscInt *cone = NULL; 8483 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 8484 8485 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8486 for (p = 0; p < closureSize*2; p += 2) { 8487 const PetscInt point = cone[p]; 8488 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8489 } 8490 if (localize) { 8491 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 8492 } 8493 if (cdof) { 8494 PetscInt coff; 8495 8496 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 8497 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 8498 } else { 8499 for (v = 0; v < coneSize; ++v) { 8500 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8501 } 8502 } 8503 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8504 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8505 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8506 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8507 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8508 8509 /* Localize new coordinates on each refined cell */ 8510 if (cdof) { 8511 PetscInt *rStar = NULL, rStarSize; 8512 8513 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8514 for (v = 0; v < rStarSize*2; v += 2) { 8515 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 8516 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 8517 8518 rc = rStar[v]; 8519 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 8520 if (!rcdof) continue; 8521 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 8522 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8523 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 8524 if (cone[p] == newv) { 8525 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 8526 break; 8527 } 8528 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 8529 } 8530 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8531 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8532 } 8533 } 8534 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8535 } 8536 } 8537 case REFINER_SIMPLEX_2D: 8538 case REFINER_HYBRID_SIMPLEX_2D: 8539 case REFINER_SIMPLEX_3D: 8540 case REFINER_HYBRID_SIMPLEX_3D: 8541 /* Edge vertices have the average of endpoint coordinates */ 8542 for (e = eStart; e < eMax; ++e) { 8543 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 8544 const PetscInt *cone; 8545 PetscInt coneSize, offA, offB, offnew, d; 8546 8547 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 8548 if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 8549 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8550 if (localize) { 8551 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 8552 PetscInt *eStar = NULL, eStarSize; 8553 PetscInt *rStar = NULL, rStarSize; 8554 PetscBool cellfound = PETSC_FALSE; 8555 8556 offA = offB = -1; 8557 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 8558 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 8559 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8560 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8561 for (v = 0; v < eStarSize*2; v += 2) { 8562 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 8563 PetscScalar coordsNewAux[3]; 8564 PetscInt *cellCone = NULL; 8565 PetscInt cellClosureSize, s, cv, cdof; 8566 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 8567 const PetscInt cell = eStar[v]; 8568 8569 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8570 if (!cdof) { 8571 /* Found a valid edge for the "vertex" part of the Section */ 8572 offA = voffA; 8573 offB = voffB; 8574 cellfound = PETSC_TRUE; 8575 } else { 8576 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8577 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8578 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 8579 const PetscInt point = cellCone[s]; 8580 if ((point >= vStart) && (point < vEnd)) { 8581 if (point == cone[0]) toffA = spaceDim*cv + coff; 8582 else if (point == cone[1]) toffB = spaceDim*cv + coff; 8583 cv++; 8584 } 8585 } 8586 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8587 for (d = 0; d < spaceDim; ++d) { 8588 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 8589 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 8590 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 8591 } 8592 /* Found a valid edge for the "vertex" part of the Section */ 8593 if (!cellfound && (locvA || locvB)) { 8594 cellfound = PETSC_TRUE; 8595 offA = toffA; 8596 offB = toffB; 8597 } 8598 } 8599 8600 /* Localize new coordinates on each refined cell */ 8601 for (s = 0; s < rStarSize*2; s += 2) { 8602 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 8603 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 8604 const PetscInt rcell = rStar[s]; 8605 8606 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8607 if (!rcdof) continue; 8608 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 8609 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8610 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8611 if (rcone[p] == newv) { 8612 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 8613 break; 8614 } 8615 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8616 } 8617 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8618 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8619 } 8620 } 8621 } 8622 } 8623 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8624 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8625 if (!cellfound) { 8626 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 8627 needcoords = PETSC_TRUE; 8628 } 8629 } else { 8630 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 8631 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 8632 } 8633 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8634 if (offA != -1 && offB != -1) { 8635 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 8636 for (d = 0; d < spaceDim; ++d) { 8637 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 8638 } 8639 } else { 8640 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8641 } 8642 } 8643 /* Old vertices have the same coordinates */ 8644 for (v = vStart; v < vEnd; ++v) { 8645 const PetscInt newv = vStartNew + (v - vStart); 8646 PetscInt off, offnew, d; 8647 8648 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 8649 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8650 for (d = 0; d < spaceDim; ++d) { 8651 coordsNew[offnew+d] = coords[off+d]; 8652 } 8653 8654 /* Localize new coordinates on each refined cell */ 8655 if (localize) { 8656 PetscInt p; 8657 PetscInt *rStar = NULL, rStarSize; 8658 8659 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8660 for (p = 0; p < rStarSize*2; p += 2) { 8661 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 8662 PetscScalar ocoords[3]; 8663 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 8664 8665 c = rStar[p]; 8666 oc = parentId[c-cStartNew]; 8667 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 8668 if (!cdof) continue; 8669 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 8670 if (!cdof) continue; 8671 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 8672 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8673 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8674 if (cone[s] == v) { 8675 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 8676 break; 8677 } 8678 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 8679 } 8680 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D",v); 8681 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8682 8683 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 8684 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8685 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8686 if (cone[s] == newv) { 8687 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 8688 break; 8689 } 8690 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 8691 } 8692 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8693 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8694 } 8695 } 8696 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8697 } 8698 } 8699 break; 8700 default: 8701 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8702 } 8703 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 8704 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8705 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 8706 8707 /* Final reduction (if needed) if we are localizing */ 8708 if (localize) { 8709 PetscBool gred; 8710 8711 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 8712 if (gred) { 8713 DM cdm; 8714 Vec aux; 8715 PetscSF sf; 8716 const PetscScalar *lArray; 8717 PetscScalar *gArray; 8718 #if defined(PETSC_USE_COMPLEX) 8719 PetscInt i, ln, gn; 8720 PetscReal *lrArray; 8721 PetscReal *grArray; 8722 #endif 8723 8724 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 8725 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 8726 ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr); 8727 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8728 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 8729 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 8730 #if defined(PETSC_USE_COMPLEX) 8731 ierr = VecGetLocalSize(aux, &gn);CHKERRQ(ierr); 8732 ierr = VecGetLocalSize(coordinatesNew, &ln);CHKERRQ(ierr); 8733 ierr = PetscMalloc2(ln,&lrArray,gn,&grArray);CHKERRQ(ierr); 8734 for (i=0;i<ln;i++) lrArray[i] = PetscRealPart(lArray[i]); 8735 for (i=0;i<gn;i++) grArray[i] = PetscRealPart(gArray[i]); 8736 ierr = PetscSFReduceBegin(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8737 ierr = PetscSFReduceEnd(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8738 for (i=0;i<gn;i++) gArray[i] = grArray[i]; 8739 ierr = PetscFree2(lrArray,grArray);CHKERRQ(ierr); 8740 #else 8741 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8742 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8743 #endif 8744 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8745 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 8746 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8747 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8748 ierr = VecDestroy(&aux);CHKERRQ(ierr); 8749 } 8750 } 8751 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 8752 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 8753 ierr = PetscFree(parentId);CHKERRQ(ierr); 8754 PetscFunctionReturn(0); 8755 } 8756 8757 /*@ 8758 DMPlexCreateProcessSF - Create an SF which just has process connectivity 8759 8760 Collective on DM 8761 8762 Input Parameters: 8763 + dm - The DM 8764 - sfPoint - The PetscSF which encodes point connectivity 8765 8766 Output Parameters: 8767 + processRanks - A list of process neighbors, or NULL 8768 - sfProcess - An SF encoding the process connectivity, or NULL 8769 8770 Level: developer 8771 8772 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 8773 @*/ 8774 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 8775 { 8776 PetscInt numRoots, numLeaves, l; 8777 const PetscInt *localPoints; 8778 const PetscSFNode *remotePoints; 8779 PetscInt *localPointsNew; 8780 PetscSFNode *remotePointsNew; 8781 PetscInt *ranks, *ranksNew; 8782 PetscMPIInt size; 8783 PetscErrorCode ierr; 8784 8785 PetscFunctionBegin; 8786 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8787 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 8788 if (processRanks) {PetscValidPointer(processRanks, 3);} 8789 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 8790 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 8791 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8792 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 8793 for (l = 0; l < numLeaves; ++l) { 8794 ranks[l] = remotePoints[l].rank; 8795 } 8796 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 8797 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 8798 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 8799 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 8800 for (l = 0; l < numLeaves; ++l) { 8801 ranksNew[l] = ranks[l]; 8802 localPointsNew[l] = l; 8803 remotePointsNew[l].index = 0; 8804 remotePointsNew[l].rank = ranksNew[l]; 8805 } 8806 ierr = PetscFree(ranks);CHKERRQ(ierr); 8807 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 8808 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 8809 if (sfProcess) { 8810 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 8811 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 8812 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 8813 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 8814 } 8815 PetscFunctionReturn(0); 8816 } 8817 8818 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8819 { 8820 PetscSF sf, sfNew, sfProcess; 8821 IS processRanks; 8822 MPI_Datatype depthType; 8823 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 8824 const PetscInt *localPoints, *neighbors; 8825 const PetscSFNode *remotePoints; 8826 PetscInt *localPointsNew; 8827 PetscSFNode *remotePointsNew; 8828 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 8829 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 8830 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8831 PetscErrorCode ierr; 8832 8833 PetscFunctionBegin; 8834 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 8835 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 8836 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 8837 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %D != %D", ldepth, depth); 8838 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8839 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8840 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8841 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8842 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 8843 cMax = cMax < 0 ? cEnd : cMax; 8844 fMax = fMax < 0 ? fEnd : fMax; 8845 eMax = eMax < 0 ? eEnd : eMax; 8846 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8847 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 8848 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 8849 /* Calculate size of new SF */ 8850 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8851 if (numRoots < 0) PetscFunctionReturn(0); 8852 for (l = 0; l < numLeaves; ++l) { 8853 const PetscInt p = localPoints[l]; 8854 8855 switch (refiner) { 8856 case REFINER_SIMPLEX_1D: 8857 if ((p >= vStart) && (p < vEnd)) { 8858 /* Interior vertices stay the same */ 8859 ++numLeavesNew; 8860 } else if ((p >= cStart && p < cMax)) { 8861 /* Interior cells add new cells and interior vertices */ 8862 numLeavesNew += 2 + 1; 8863 } 8864 break; 8865 case REFINER_SIMPLEX_2D: 8866 case REFINER_HYBRID_SIMPLEX_2D: 8867 if ((p >= vStart) && (p < vEnd)) { 8868 /* Interior vertices stay the same */ 8869 ++numLeavesNew; 8870 } else if ((p >= fStart) && (p < fMax)) { 8871 /* Interior faces add new faces and vertex */ 8872 numLeavesNew += 2 + 1; 8873 } else if ((p >= fMax) && (p < fEnd)) { 8874 /* Hybrid faces stay the same */ 8875 ++numLeavesNew; 8876 } else if ((p >= cStart) && (p < cMax)) { 8877 /* Interior cells add new cells and interior faces */ 8878 numLeavesNew += 4 + 3; 8879 } else if ((p >= cMax) && (p < cEnd)) { 8880 /* Hybrid cells add new cells and hybrid face */ 8881 numLeavesNew += 2 + 1; 8882 } 8883 break; 8884 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8885 case REFINER_SIMPLEX_TO_HEX_2D: 8886 if ((p >= vStart) && (p < vEnd)) { 8887 /* Interior vertices stay the same */ 8888 ++numLeavesNew; 8889 } else if ((p >= fStart) && (p < fEnd)) { 8890 /* Interior faces add new faces and vertex */ 8891 numLeavesNew += 2 + 1; 8892 } else if ((p >= cStart) && (p < cMax)) { 8893 /* Interior cells add new cells, interior faces, and vertex */ 8894 numLeavesNew += 3 + 3 + 1; 8895 } else if ((p >= cMax) && (p < cEnd)) { 8896 /* Hybrid cells add new cells, interior faces, and vertex */ 8897 numLeavesNew += 4 + 4 + 1; 8898 } 8899 break; 8900 case REFINER_HEX_2D: 8901 case REFINER_HYBRID_HEX_2D: 8902 if ((p >= vStart) && (p < vEnd)) { 8903 /* Interior vertices stay the same */ 8904 ++numLeavesNew; 8905 } else if ((p >= fStart) && (p < fMax)) { 8906 /* Interior faces add new faces and vertex */ 8907 numLeavesNew += 2 + 1; 8908 } else if ((p >= fMax) && (p < fEnd)) { 8909 /* Hybrid faces stay the same */ 8910 ++numLeavesNew; 8911 } else if ((p >= cStart) && (p < cMax)) { 8912 /* Interior cells add new cells, interior faces, and vertex */ 8913 numLeavesNew += 4 + 4 + 1; 8914 } else if ((p >= cMax) && (p < cEnd)) { 8915 /* Hybrid cells add new cells and hybrid face */ 8916 numLeavesNew += 2 + 1; 8917 } 8918 break; 8919 case REFINER_SIMPLEX_3D: 8920 case REFINER_HYBRID_SIMPLEX_3D: 8921 if ((p >= vStart) && (p < vEnd)) { 8922 /* Interior vertices stay the same */ 8923 ++numLeavesNew; 8924 } else if ((p >= eStart) && (p < eMax)) { 8925 /* Interior edges add new edges and vertex */ 8926 numLeavesNew += 2 + 1; 8927 } else if ((p >= eMax) && (p < eEnd)) { 8928 /* Hybrid edges stay the same */ 8929 ++numLeavesNew; 8930 } else if ((p >= fStart) && (p < fMax)) { 8931 /* Interior faces add new faces and edges */ 8932 numLeavesNew += 4 + 3; 8933 } else if ((p >= fMax) && (p < fEnd)) { 8934 /* Hybrid faces add new faces and edges */ 8935 numLeavesNew += 2 + 1; 8936 } else if ((p >= cStart) && (p < cMax)) { 8937 /* Interior cells add new cells, faces, and edges */ 8938 numLeavesNew += 8 + 8 + 1; 8939 } else if ((p >= cMax) && (p < cEnd)) { 8940 /* Hybrid cells add new cells and faces */ 8941 numLeavesNew += 4 + 3; 8942 } 8943 break; 8944 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8945 case REFINER_SIMPLEX_TO_HEX_3D: 8946 if ((p >= vStart) && (p < vEnd)) { 8947 /* Interior vertices stay the same */ 8948 ++numLeavesNew; 8949 } else if ((p >= eStart) && (p < eMax)) { 8950 /* Interior edges add new edges and vertex */ 8951 numLeavesNew += 2 + 1; 8952 } else if ((p >= eMax) && (p < eEnd)) { 8953 /* Hybrid edges stay the same */ 8954 ++numLeavesNew; 8955 } else if ((p >= fStart) && (p < fMax)) { 8956 /* Interior faces add new faces, edges and a vertex */ 8957 numLeavesNew += 3 + 3 + 1; 8958 } else if ((p >= fMax) && (p < fEnd)) { 8959 /* Hybrid faces add new faces and an edge */ 8960 numLeavesNew += 2 + 1; 8961 } else if ((p >= cStart) && (p < cMax)) { 8962 /* Interior cells add new cells, faces, edges and a vertex */ 8963 numLeavesNew += 4 + 6 + 4 + 1; 8964 } else if ((p >= cMax) && (p < cEnd)) { 8965 /* Hybrid cells add new cells, faces and an edge */ 8966 numLeavesNew += 3 + 3 + 1; 8967 } 8968 break; 8969 case REFINER_HEX_3D: 8970 case REFINER_HYBRID_HEX_3D: 8971 if ((p >= vStart) && (p < vEnd)) { 8972 /* Old vertices stay the same */ 8973 ++numLeavesNew; 8974 } else if ((p >= eStart) && (p < eMax)) { 8975 /* Interior edges add new edges, and vertex */ 8976 numLeavesNew += 2 + 1; 8977 } else if ((p >= eMax) && (p < eEnd)) { 8978 /* Hybrid edges stay the same */ 8979 ++numLeavesNew; 8980 } else if ((p >= fStart) && (p < fMax)) { 8981 /* Interior faces add new faces, edges, and vertex */ 8982 numLeavesNew += 4 + 4 + 1; 8983 } else if ((p >= fMax) && (p < fEnd)) { 8984 /* Hybrid faces add new faces and edges */ 8985 numLeavesNew += 2 + 1; 8986 } else if ((p >= cStart) && (p < cMax)) { 8987 /* Interior cells add new cells, faces, edges, and vertex */ 8988 numLeavesNew += 8 + 12 + 6 + 1; 8989 } else if ((p >= cStart) && (p < cEnd)) { 8990 /* Hybrid cells add new cells, faces, and edges */ 8991 numLeavesNew += 4 + 4 + 1; 8992 } 8993 break; 8994 default: 8995 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8996 } 8997 } 8998 /* Communicate depthSizes for each remote rank */ 8999 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 9000 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 9001 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 9002 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 9003 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 9004 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 9005 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9006 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9007 for (n = 0; n < numNeighbors; ++n) { 9008 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 9009 } 9010 depthSizeOld[depth] = cMax; 9011 depthSizeOld[0] = vMax; 9012 depthSizeOld[depth-1] = fMax; 9013 depthSizeOld[1] = eMax; 9014 9015 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9016 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9017 9018 depthSizeOld[depth] = cEnd - cStart; 9019 depthSizeOld[0] = vEnd - vStart; 9020 depthSizeOld[depth-1] = fEnd - fStart; 9021 depthSizeOld[1] = eEnd - eStart; 9022 9023 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9024 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9025 for (n = 0; n < numNeighbors; ++n) { 9026 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 9027 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 9028 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]; 9029 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 9030 } 9031 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 9032 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 9033 /* Calculate new point SF */ 9034 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 9035 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 9036 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 9037 for (l = 0, m = 0; l < numLeaves; ++l) { 9038 PetscInt p = localPoints[l]; 9039 PetscInt rp = remotePoints[l].index, n; 9040 PetscMPIInt rrank = remotePoints[l].rank; 9041 9042 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 9043 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rrank); 9044 switch (refiner) { 9045 case REFINER_SIMPLEX_1D: 9046 if ((p >= vStart) && (p < vEnd)) { 9047 /* Old vertices stay the same */ 9048 localPointsNew[m] = vStartNew + (p - vStart); 9049 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9050 remotePointsNew[m].rank = rrank; 9051 ++m; 9052 } else if ((p >= cStart) && (p < cMax)) { 9053 /* Old interior cells add new cells and vertex */ 9054 for (r = 0; r < 2; ++r, ++m) { 9055 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 9056 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 9057 remotePointsNew[m].rank = rrank; 9058 } 9059 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 9060 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 9061 remotePointsNew[m].rank = rrank; 9062 ++m; 9063 } 9064 break; 9065 case REFINER_SIMPLEX_2D: 9066 case REFINER_HYBRID_SIMPLEX_2D: 9067 if ((p >= vStart) && (p < vEnd)) { 9068 /* Old vertices stay the same */ 9069 localPointsNew[m] = vStartNew + (p - vStart); 9070 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9071 remotePointsNew[m].rank = rrank; 9072 ++m; 9073 } else if ((p >= fStart) && (p < fMax)) { 9074 /* Old interior faces add new faces and vertex */ 9075 for (r = 0; r < 2; ++r, ++m) { 9076 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9077 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9078 remotePointsNew[m].rank = rrank; 9079 } 9080 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9081 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9082 remotePointsNew[m].rank = rrank; 9083 ++m; 9084 } else if ((p >= fMax) && (p < fEnd)) { 9085 /* Old hybrid faces stay the same */ 9086 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9087 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9088 remotePointsNew[m].rank = rrank; 9089 ++m; 9090 } else if ((p >= cStart) && (p < cMax)) { 9091 /* Old interior cells add new cells and interior faces */ 9092 for (r = 0; r < 4; ++r, ++m) { 9093 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9094 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9095 remotePointsNew[m].rank = rrank; 9096 } 9097 for (r = 0; r < 3; ++r, ++m) { 9098 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 9099 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 9100 remotePointsNew[m].rank = rrank; 9101 } 9102 } else if ((p >= cMax) && (p < cEnd)) { 9103 /* Old hybrid cells add new cells and hybrid face */ 9104 for (r = 0; r < 2; ++r, ++m) { 9105 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9106 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9107 remotePointsNew[m].rank = rrank; 9108 } 9109 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9110 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]); 9111 remotePointsNew[m].rank = rrank; 9112 ++m; 9113 } 9114 break; 9115 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9116 case REFINER_SIMPLEX_TO_HEX_2D: 9117 if ((p >= vStart) && (p < vEnd)) { 9118 /* Old vertices stay the same */ 9119 localPointsNew[m] = vStartNew + (p - vStart); 9120 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9121 remotePointsNew[m].rank = rrank; 9122 ++m; 9123 } else if ((p >= fStart) && (p < fEnd)) { 9124 /* Old interior faces add new faces and vertex */ 9125 for (r = 0; r < 2; ++r, ++m) { 9126 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9127 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9128 remotePointsNew[m].rank = rrank; 9129 } 9130 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9131 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9132 remotePointsNew[m].rank = rrank; 9133 ++m; 9134 } else if ((p >= cStart) && (p < cMax)) { 9135 /* Old interior cells add new cells, interior faces, and a vertex */ 9136 for (r = 0; r < 3; ++r, ++m) { 9137 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 9138 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 9139 remotePointsNew[m].rank = rrank; 9140 } 9141 for (r = 0; r < 3; ++r, ++m) { 9142 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9143 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 9144 remotePointsNew[m].rank = rrank; 9145 } 9146 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9147 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9148 remotePointsNew[m].rank = rrank; 9149 ++m; 9150 } else if ((p >= cMax) && (p < cEnd)) { 9151 /* Old interior hybrid cells add new cells, interior faces, and a vertex */ 9152 for (r = 0; r < 4; ++r, ++m) { 9153 localPointsNew[m] = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9154 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9155 remotePointsNew[m].rank = rrank; 9156 } 9157 for (r = 0; r < 4; ++r, ++m) { 9158 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9159 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; 9160 remotePointsNew[m].rank = rrank; 9161 } 9162 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9163 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9164 remotePointsNew[m].rank = rrank; 9165 ++m; 9166 } 9167 break; 9168 case REFINER_HEX_2D: 9169 case REFINER_HYBRID_HEX_2D: 9170 if ((p >= vStart) && (p < vEnd)) { 9171 /* Old vertices stay the same */ 9172 localPointsNew[m] = vStartNew + (p - vStart); 9173 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9174 remotePointsNew[m].rank = rrank; 9175 ++m; 9176 } else if ((p >= fStart) && (p < fMax)) { 9177 /* Old interior faces add new faces and vertex */ 9178 for (r = 0; r < 2; ++r, ++m) { 9179 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9180 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9181 remotePointsNew[m].rank = rrank; 9182 } 9183 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9184 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9185 remotePointsNew[m].rank = rrank; 9186 ++m; 9187 } else if ((p >= fMax) && (p < fEnd)) { 9188 /* Old hybrid faces stay the same */ 9189 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9190 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9191 remotePointsNew[m].rank = rrank; 9192 ++m; 9193 } else if ((p >= cStart) && (p < cMax)) { 9194 /* Old interior cells add new cells, interior faces, and vertex */ 9195 for (r = 0; r < 4; ++r, ++m) { 9196 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9197 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9198 remotePointsNew[m].rank = rrank; 9199 } 9200 for (r = 0; r < 4; ++r, ++m) { 9201 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 9202 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 9203 remotePointsNew[m].rank = rrank; 9204 } 9205 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 9206 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 9207 remotePointsNew[m].rank = rrank; 9208 ++m; 9209 } else if ((p >= cStart) && (p < cMax)) { 9210 /* Old hybrid cells add new cells and hybrid face */ 9211 for (r = 0; r < 2; ++r, ++m) { 9212 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; /* TODO: is this a bug? */ 9213 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; /* TODO: is this a bug? */ 9214 remotePointsNew[m].rank = rrank; 9215 } 9216 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9217 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]); 9218 remotePointsNew[m].rank = rrank; 9219 ++m; 9220 } 9221 break; 9222 case REFINER_SIMPLEX_3D: 9223 case REFINER_HYBRID_SIMPLEX_3D: 9224 if ((p >= vStart) && (p < vEnd)) { 9225 /* Interior vertices stay the same */ 9226 localPointsNew[m] = vStartNew + (p - vStart); 9227 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9228 remotePointsNew[m].rank = rrank; 9229 ++m; 9230 } else if ((p >= eStart) && (p < eMax)) { 9231 /* Interior edges add new edges and vertex */ 9232 for (r = 0; r < 2; ++r, ++m) { 9233 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9234 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9235 remotePointsNew[m].rank = rrank; 9236 } 9237 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9238 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9239 remotePointsNew[m].rank = rrank; 9240 ++m; 9241 } else if ((p >= eMax) && (p < eEnd)) { 9242 /* Hybrid edges stay the same */ 9243 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 9244 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rp - rdepthMaxOld[n*(depth+1)+1]); 9245 remotePointsNew[m].rank = rrank; 9246 ++m; 9247 } else if ((p >= fStart) && (p < fMax)) { 9248 /* Interior faces add new faces and edges */ 9249 for (r = 0; r < 4; ++r, ++m) { 9250 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9251 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9252 remotePointsNew[m].rank = rrank; 9253 } 9254 for (r = 0; r < 3; ++r, ++m) { 9255 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9256 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9257 remotePointsNew[m].rank = rrank; 9258 } 9259 } else if ((p >= fMax) && (p < fEnd)) { 9260 /* Hybrid faces add new faces and edges */ 9261 for (r = 0; r < 2; ++r, ++m) { 9262 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 9263 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; 9264 remotePointsNew[m].rank = rrank; 9265 } 9266 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 9267 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]); 9268 remotePointsNew[m].rank = rrank; 9269 ++m; 9270 } else if ((p >= cStart) && (p < cMax)) { 9271 /* Interior cells add new cells, faces, and edges */ 9272 for (r = 0; r < 8; ++r, ++m) { 9273 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9274 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9275 remotePointsNew[m].rank = rrank; 9276 } 9277 for (r = 0; r < 8; ++r, ++m) { 9278 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 9279 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 9280 remotePointsNew[m].rank = rrank; 9281 } 9282 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 9283 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; 9284 remotePointsNew[m].rank = rrank; 9285 ++m; 9286 } else if ((p >= cMax) && (p < cEnd)) { 9287 /* Hybrid cells add new cells and faces */ 9288 for (r = 0; r < 4; ++r, ++m) { 9289 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9290 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9291 remotePointsNew[m].rank = rrank; 9292 } 9293 for (r = 0; r < 3; ++r, ++m) { 9294 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9295 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; 9296 remotePointsNew[m].rank = rrank; 9297 } 9298 } 9299 break; 9300 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9301 case REFINER_SIMPLEX_TO_HEX_3D: 9302 if ((p >= vStart) && (p < vEnd)) { 9303 /* Interior vertices stay the same */ 9304 localPointsNew[m] = vStartNew + (p - vStart); 9305 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9306 remotePointsNew[m].rank = rrank; 9307 ++m; 9308 } else if ((p >= eStart) && (p < eMax)) { 9309 /* Interior edges add new edges and vertex */ 9310 for (r = 0; r < 2; ++r, ++m) { 9311 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9312 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9313 remotePointsNew[m].rank = rrank; 9314 } 9315 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9316 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9317 remotePointsNew[m].rank = rrank; 9318 ++m; 9319 } else if ((p >= eMax) && (p < eEnd)) { 9320 /* Hybrid edges stay the same */ 9321 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (p - eMax); 9322 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]); 9323 remotePointsNew[m].rank = rrank; 9324 ++m; 9325 } else if ((p >= fStart) && (p < fMax)) { 9326 /* Interior faces add new faces, edges and a vertex */ 9327 for (r = 0; r < 3; ++r, ++m) { 9328 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 9329 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 9330 remotePointsNew[m].rank = rrank; 9331 } 9332 for (r = 0; r < 3; ++r, ++m) { 9333 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9334 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9335 remotePointsNew[m].rank = rrank; 9336 } 9337 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9338 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9339 remotePointsNew[m].rank = rrank; 9340 ++m; 9341 } else if ((p >= fMax) && (p < fEnd)) { 9342 /* Interior hybrid faces add new faces and an edge */ 9343 for (r = 0; r < 2; ++r, ++m) { 9344 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9345 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; 9346 remotePointsNew[m].rank = rrank; 9347 } 9348 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9349 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]); 9350 remotePointsNew[m].rank = rrank; 9351 ++m; 9352 } else if ((p >= cStart) && (p < cMax)) { 9353 /* Interior cells add new cells, faces, edges, and a vertex */ 9354 for (r = 0; r < 4; ++r, ++m) { 9355 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9356 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9357 remotePointsNew[m].rank = rrank; 9358 } 9359 for (r = 0; r < 6; ++r, ++m) { 9360 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9361 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*6 + r; 9362 remotePointsNew[m].rank = rrank; 9363 } 9364 for (r = 0; r < 4; ++r, ++m) { 9365 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9366 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; 9367 remotePointsNew[m].rank = rrank; 9368 } 9369 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 9370 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]); 9371 remotePointsNew[m].rank = rrank; 9372 ++m; 9373 } else if ((p >= cMax) && (p < cEnd)) { 9374 /* Interior hybrid cells add new cells, faces and an edge */ 9375 for (r = 0; r < 3; ++r, ++m) { 9376 localPointsNew[m] = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9377 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 9378 remotePointsNew[m].rank = rrank; 9379 } 9380 for (r = 0; r < 3; ++r, ++m) { 9381 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9382 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; 9383 remotePointsNew[m].rank = rrank; 9384 } 9385 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9386 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]); 9387 remotePointsNew[m].rank = rrank; 9388 ++m; 9389 } 9390 break; 9391 case REFINER_HEX_3D: 9392 case REFINER_HYBRID_HEX_3D: 9393 if ((p >= vStart) && (p < vEnd)) { 9394 /* Interior vertices stay the same */ 9395 localPointsNew[m] = vStartNew + (p - vStart); 9396 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9397 remotePointsNew[m].rank = rrank; 9398 ++m; 9399 } else if ((p >= eStart) && (p < eMax)) { 9400 /* Interior edges add new edges and vertex */ 9401 for (r = 0; r < 2; ++r, ++m) { 9402 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9403 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9404 remotePointsNew[m].rank = rrank; 9405 } 9406 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9407 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9408 remotePointsNew[m].rank = rrank; 9409 ++m; 9410 } else if ((p >= eMax) && (p < eEnd)) { 9411 /* Hybrid edges stay the same */ 9412 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 9413 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]); 9414 remotePointsNew[m].rank = rrank; 9415 ++m; 9416 } else if ((p >= fStart) && (p < fMax)) { 9417 /* Interior faces add new faces, edges, and vertex */ 9418 for (r = 0; r < 4; ++r, ++m) { 9419 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9420 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9421 remotePointsNew[m].rank = rrank; 9422 } 9423 for (r = 0; r < 4; ++r, ++m) { 9424 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 9425 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 9426 remotePointsNew[m].rank = rrank; 9427 } 9428 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9429 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9430 remotePointsNew[m].rank = rrank; 9431 ++m; 9432 } else if ((p >= fMax) && (p < fEnd)) { 9433 /* Hybrid faces add new faces and edges */ 9434 for (r = 0; r < 2; ++r, ++m) { 9435 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 9436 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; 9437 remotePointsNew[m].rank = rrank; 9438 } 9439 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 9440 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]); 9441 remotePointsNew[m].rank = rrank; 9442 ++m; 9443 } else if ((p >= cStart) && (p < cMax)) { 9444 /* Interior cells add new cells, faces, edges, and vertex */ 9445 for (r = 0; r < 8; ++r, ++m) { 9446 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9447 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9448 remotePointsNew[m].rank = rrank; 9449 } 9450 for (r = 0; r < 12; ++r, ++m) { 9451 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 9452 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 9453 remotePointsNew[m].rank = rrank; 9454 } 9455 for (r = 0; r < 6; ++r, ++m) { 9456 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 9457 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; 9458 remotePointsNew[m].rank = rrank; 9459 } 9460 for (r = 0; r < 1; ++r, ++m) { 9461 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 9462 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 9463 remotePointsNew[m].rank = rrank; 9464 } 9465 } else if ((p >= cMax) && (p < cEnd)) { 9466 /* Hybrid cells add new cells, faces, and edges */ 9467 for (r = 0; r < 4; ++r, ++m) { 9468 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9469 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9470 remotePointsNew[m].rank = rrank; 9471 } 9472 for (r = 0; r < 4; ++r, ++m) { 9473 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 9474 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; 9475 remotePointsNew[m].rank = rrank; 9476 } 9477 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9478 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]); 9479 remotePointsNew[m].rank = rrank; 9480 ++m; 9481 } 9482 break; 9483 default: 9484 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9485 } 9486 } 9487 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 9488 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 9489 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 9490 { 9491 PetscSFNode *rp, *rtmp; 9492 PetscInt *lp, *idx, *ltmp, i; 9493 9494 /* SF needs sorted leaves to correct calculate Gather */ 9495 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 9496 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 9497 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 9498 for (i = 0; i < numLeavesNew; ++i) { 9499 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); 9500 idx[i] = i; 9501 } 9502 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 9503 for (i = 0; i < numLeavesNew; ++i) { 9504 lp[i] = localPointsNew[idx[i]]; 9505 rp[i] = remotePointsNew[idx[i]]; 9506 } 9507 ltmp = localPointsNew; 9508 localPointsNew = lp; 9509 rtmp = remotePointsNew; 9510 remotePointsNew = rp; 9511 ierr = PetscFree(idx);CHKERRQ(ierr); 9512 ierr = PetscFree(ltmp);CHKERRQ(ierr); 9513 ierr = PetscFree(rtmp);CHKERRQ(ierr); 9514 } 9515 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 9516 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 9517 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 9518 PetscFunctionReturn(0); 9519 } 9520 9521 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 9522 { 9523 PetscInt numLabels, l; 9524 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 9525 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 9526 PetscErrorCode ierr; 9527 9528 PetscFunctionBegin; 9529 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 9530 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 9531 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9532 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 9533 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 9534 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 9535 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 9536 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 9537 switch (refiner) { 9538 case REFINER_NOOP: 9539 case REFINER_SIMPLEX_1D: 9540 case REFINER_SIMPLEX_2D: 9541 case REFINER_SIMPLEX_TO_HEX_2D: 9542 case REFINER_HEX_2D: 9543 case REFINER_SIMPLEX_3D: 9544 case REFINER_HEX_3D: 9545 case REFINER_SIMPLEX_TO_HEX_3D: 9546 break; 9547 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9548 case REFINER_HYBRID_SIMPLEX_3D: 9549 case REFINER_HYBRID_HEX_3D: 9550 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 9551 case REFINER_HYBRID_SIMPLEX_2D: 9552 case REFINER_HYBRID_HEX_2D: 9553 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 9554 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9555 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 9556 break; 9557 default: 9558 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9559 } 9560 cMax = cMax < 0 ? cEnd : cMax; 9561 fMax = fMax < 0 ? fEnd : fMax; 9562 eMax = eMax < 0 ? eEnd : eMax; 9563 for (l = 0; l < numLabels; ++l) { 9564 DMLabel label, labelNew; 9565 const char *lname; 9566 PetscBool isDepth; 9567 IS valueIS; 9568 const PetscInt *values; 9569 PetscInt defVal; 9570 PetscInt numValues, val; 9571 9572 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 9573 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 9574 if (isDepth) continue; 9575 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 9576 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 9577 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 9578 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 9579 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 9580 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 9581 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 9582 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 9583 for (val = 0; val < numValues; ++val) { 9584 IS pointIS; 9585 const PetscInt *points; 9586 PetscInt numPoints, n; 9587 9588 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 9589 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 9590 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 9591 /* Ensure refined label is created with same number of strata as 9592 * original (even if no entries here). */ 9593 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 9594 for (n = 0; n < numPoints; ++n) { 9595 const PetscInt p = points[n]; 9596 switch (refiner) { 9597 case REFINER_SIMPLEX_1D: 9598 if ((p >= vStart) && (p < vEnd)) { 9599 /* Old vertices stay the same */ 9600 newp = vStartNew + (p - vStart); 9601 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9602 } else if ((p >= cStart) && (p < cEnd)) { 9603 /* Old cells add new cells and vertex */ 9604 newp = vStartNew + (vEnd - vStart) + (p - cStart); 9605 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9606 for (r = 0; r < 2; ++r) { 9607 newp = cStartNew + (p - cStart)*2 + r; 9608 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9609 } 9610 } 9611 break; 9612 case REFINER_SIMPLEX_2D: 9613 if ((p >= vStart) && (p < vEnd)) { 9614 /* Old vertices stay the same */ 9615 newp = vStartNew + (p - vStart); 9616 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9617 } else if ((p >= fStart) && (p < fEnd)) { 9618 /* Old faces add new faces and vertex */ 9619 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9620 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9621 for (r = 0; r < 2; ++r) { 9622 newp = fStartNew + (p - fStart)*2 + r; 9623 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9624 } 9625 } else if ((p >= cStart) && (p < cEnd)) { 9626 /* Old cells add new cells and interior faces */ 9627 for (r = 0; r < 4; ++r) { 9628 newp = cStartNew + (p - cStart)*4 + r; 9629 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9630 } 9631 for (r = 0; r < 3; ++r) { 9632 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9633 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9634 } 9635 } 9636 break; 9637 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9638 case REFINER_SIMPLEX_TO_HEX_2D: 9639 if ((p >= vStart) && (p < vEnd)) { 9640 /* Old vertices stay the same */ 9641 newp = vStartNew + (p - vStart); 9642 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9643 } else if ((p >= fStart) && (p < fEnd)) { 9644 /* Old faces add new faces and vertex */ 9645 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9646 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9647 for (r = 0; r < 2; ++r) { 9648 newp = fStartNew + (p - fStart)*2 + r; 9649 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9650 } 9651 } else if ((p >= cStart) && (p < cMax)) { 9652 /* Old cells add new cells, interior faces, and a vertex */ 9653 for (r = 0; r < 3; ++r) { 9654 newp = cStartNew + (p - cStart)*3 + r; 9655 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9656 } 9657 for (r = 0; r < 3; ++r) { 9658 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9659 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9660 } 9661 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9662 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9663 } else if ((p >= cMax) && (p < cEnd)) { 9664 /* Old hybrid cells add new cells, interior faces, and a vertex */ 9665 for (r = 0; r < 4; ++r) { 9666 newp = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9667 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9668 } 9669 for (r = 0; r < 4; ++r) { 9670 newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9671 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9672 } 9673 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9674 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9675 } 9676 break; 9677 case REFINER_HEX_2D: 9678 if ((p >= vStart) && (p < vEnd)) { 9679 /* Old vertices stay the same */ 9680 newp = vStartNew + (p - vStart); 9681 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9682 } else if ((p >= fStart) && (p < fEnd)) { 9683 /* Old faces add new faces and vertex */ 9684 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9685 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9686 for (r = 0; r < 2; ++r) { 9687 newp = fStartNew + (p - fStart)*2 + r; 9688 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9689 } 9690 } else if ((p >= cStart) && (p < cEnd)) { 9691 /* Old cells add new cells and interior faces and vertex */ 9692 for (r = 0; r < 4; ++r) { 9693 newp = cStartNew + (p - cStart)*4 + r; 9694 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9695 } 9696 for (r = 0; r < 4; ++r) { 9697 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9698 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9699 } 9700 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9701 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9702 } 9703 break; 9704 case REFINER_HYBRID_SIMPLEX_2D: 9705 if ((p >= vStart) && (p < vEnd)) { 9706 /* Old vertices stay the same */ 9707 newp = vStartNew + (p - vStart); 9708 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9709 } else if ((p >= fStart) && (p < fMax)) { 9710 /* Old interior faces add new faces and vertex */ 9711 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9712 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9713 for (r = 0; r < 2; ++r) { 9714 newp = fStartNew + (p - fStart)*2 + r; 9715 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9716 } 9717 } else if ((p >= fMax) && (p < fEnd)) { 9718 /* Old hybrid faces stay the same */ 9719 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9720 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9721 } else if ((p >= cStart) && (p < cMax)) { 9722 /* Old interior cells add new cells and interior faces */ 9723 for (r = 0; r < 4; ++r) { 9724 newp = cStartNew + (p - cStart)*4 + r; 9725 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9726 } 9727 for (r = 0; r < 3; ++r) { 9728 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9729 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9730 } 9731 } else if ((p >= cMax) && (p < cEnd)) { 9732 /* Old hybrid cells add new cells and hybrid face */ 9733 for (r = 0; r < 2; ++r) { 9734 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9735 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9736 } 9737 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9738 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9739 } 9740 break; 9741 case REFINER_HYBRID_HEX_2D: 9742 if ((p >= vStart) && (p < vEnd)) { 9743 /* Old vertices stay the same */ 9744 newp = vStartNew + (p - vStart); 9745 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9746 } else if ((p >= fStart) && (p < fMax)) { 9747 /* Old interior faces add new faces and vertex */ 9748 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9749 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9750 for (r = 0; r < 2; ++r) { 9751 newp = fStartNew + (p - fStart)*2 + r; 9752 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9753 } 9754 } else if ((p >= fMax) && (p < fEnd)) { 9755 /* Old hybrid faces stay the same */ 9756 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9757 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9758 } else if ((p >= cStart) && (p < cMax)) { 9759 /* Old interior cells add new cells, interior faces, and vertex */ 9760 for (r = 0; r < 4; ++r) { 9761 newp = cStartNew + (p - cStart)*4 + r; 9762 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9763 } 9764 for (r = 0; r < 4; ++r) { 9765 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9766 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9767 } 9768 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9769 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9770 } else if ((p >= cMax) && (p < cEnd)) { 9771 /* Old hybrid cells add new cells and hybrid face */ 9772 for (r = 0; r < 2; ++r) { 9773 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9774 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9775 } 9776 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9777 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9778 } 9779 break; 9780 case REFINER_SIMPLEX_3D: 9781 if ((p >= vStart) && (p < vEnd)) { 9782 /* Old vertices stay the same */ 9783 newp = vStartNew + (p - vStart); 9784 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9785 } else if ((p >= eStart) && (p < eEnd)) { 9786 /* Old edges add new edges and vertex */ 9787 for (r = 0; r < 2; ++r) { 9788 newp = eStartNew + (p - eStart)*2 + r; 9789 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9790 } 9791 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9792 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9793 } else if ((p >= fStart) && (p < fEnd)) { 9794 /* Old faces add new faces and edges */ 9795 for (r = 0; r < 4; ++r) { 9796 newp = fStartNew + (p - fStart)*4 + r; 9797 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9798 } 9799 for (r = 0; r < 3; ++r) { 9800 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 9801 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9802 } 9803 } else if ((p >= cStart) && (p < cEnd)) { 9804 /* Old cells add new cells and interior faces and edges */ 9805 for (r = 0; r < 8; ++r) { 9806 newp = cStartNew + (p - cStart)*8 + r; 9807 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9808 } 9809 for (r = 0; r < 8; ++r) { 9810 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 9811 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9812 } 9813 for (r = 0; r < 1; ++r) { 9814 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 9815 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9816 } 9817 } 9818 break; 9819 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9820 case REFINER_SIMPLEX_TO_HEX_3D: 9821 if ((p >= vStart) && (p < vEnd)) { 9822 /* Old vertices stay the same */ 9823 newp = vStartNew + (p - vStart); 9824 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9825 } else if ((p >= eStart) && (p < eMax)) { 9826 /* Interior edges add new edges and vertex */ 9827 for (r = 0; r < 2; ++r) { 9828 newp = eStartNew + (p - eStart)*2 + r; 9829 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9830 } 9831 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9832 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9833 } else if ((p >= eMax) && (p < eEnd)) { 9834 /* Hybrid edges stay the same */ 9835 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + p - eMax; 9836 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9837 } else if ((p >= fStart) && (p < fMax)) { 9838 /* Old faces add new faces, edges and a vertex */ 9839 for (r = 0; r < 3; ++r) { 9840 newp = fStartNew + (p - fStart)*3 + r; 9841 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9842 } 9843 for (r = 0; r < 3; ++r) { 9844 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9845 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9846 } 9847 } else if ((p >= fMax) && (p < fEnd)) { 9848 /* Old hybrid faces add new faces and an edge */ 9849 for (r = 0; r < 2; ++r) { 9850 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9851 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9852 } 9853 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9854 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9855 } else if ((p >= cStart) && (p < cMax)) { 9856 /* Old cells add new cells and interior faces and edges and a vertex */ 9857 for (r = 0; r < 4; ++r) { 9858 newp = cStartNew + (p - cStart)*4 + r; 9859 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9860 } 9861 for (r = 0; r < 6; ++r) { 9862 newp = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9863 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9864 } 9865 for (r = 0; r < 4; ++r) { 9866 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9867 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9868 } 9869 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + p - cStart; 9870 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9871 } else if ((p >= cMax) && (p < cEnd)) { 9872 /* Old hybrid cells add new cells and interior faces and an edge */ 9873 for (r = 0; r < 3; ++r) { 9874 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9875 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9876 } 9877 for (r = 0; r < 3; ++r) { 9878 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9879 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9880 } 9881 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + p - cMax; 9882 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9883 } 9884 break; 9885 case REFINER_HYBRID_SIMPLEX_3D: 9886 if ((p >= vStart) && (p < vEnd)) { 9887 /* Interior vertices stay the same */ 9888 newp = vStartNew + (p - vStart); 9889 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9890 } else if ((p >= eStart) && (p < eMax)) { 9891 /* Interior edges add new edges and vertex */ 9892 for (r = 0; r < 2; ++r) { 9893 newp = eStartNew + (p - eStart)*2 + r; 9894 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9895 } 9896 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9897 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9898 } else if ((p >= eMax) && (p < eEnd)) { 9899 /* Hybrid edges stay the same */ 9900 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 9901 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9902 } else if ((p >= fStart) && (p < fMax)) { 9903 /* Interior faces add new faces and edges */ 9904 for (r = 0; r < 4; ++r) { 9905 newp = fStartNew + (p - fStart)*4 + r; 9906 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9907 } 9908 for (r = 0; r < 3; ++r) { 9909 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9910 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9911 } 9912 } else if ((p >= fMax) && (p < fEnd)) { 9913 /* Hybrid faces add new faces and edges */ 9914 for (r = 0; r < 2; ++r) { 9915 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 9916 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9917 } 9918 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 9919 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9920 } else if ((p >= cStart) && (p < cMax)) { 9921 /* Interior cells add new cells, faces, and edges */ 9922 for (r = 0; r < 8; ++r) { 9923 newp = cStartNew + (p - cStart)*8 + r; 9924 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9925 } 9926 for (r = 0; r < 8; ++r) { 9927 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 9928 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9929 } 9930 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 9931 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9932 } else if ((p >= cMax) && (p < cEnd)) { 9933 /* Hybrid cells add new cells and faces */ 9934 for (r = 0; r < 4; ++r) { 9935 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9936 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9937 } 9938 for (r = 0; r < 3; ++r) { 9939 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9940 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9941 } 9942 } 9943 break; 9944 case REFINER_HEX_3D: 9945 if ((p >= vStart) && (p < vEnd)) { 9946 /* Old vertices stay the same */ 9947 newp = vStartNew + (p - vStart); 9948 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9949 } else if ((p >= eStart) && (p < eEnd)) { 9950 /* Old edges add new edges and vertex */ 9951 for (r = 0; r < 2; ++r) { 9952 newp = eStartNew + (p - eStart)*2 + r; 9953 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9954 } 9955 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9956 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9957 } else if ((p >= fStart) && (p < fEnd)) { 9958 /* Old faces add new faces, edges, and vertex */ 9959 for (r = 0; r < 4; ++r) { 9960 newp = fStartNew + (p - fStart)*4 + r; 9961 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9962 } 9963 for (r = 0; r < 4; ++r) { 9964 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 9965 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9966 } 9967 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 9968 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9969 } else if ((p >= cStart) && (p < cEnd)) { 9970 /* Old cells add new cells, faces, edges, and vertex */ 9971 for (r = 0; r < 8; ++r) { 9972 newp = cStartNew + (p - cStart)*8 + r; 9973 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9974 } 9975 for (r = 0; r < 12; ++r) { 9976 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 9977 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9978 } 9979 for (r = 0; r < 6; ++r) { 9980 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 9981 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9982 } 9983 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 9984 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9985 } 9986 break; 9987 case REFINER_HYBRID_HEX_3D: 9988 if ((p >= vStart) && (p < vEnd)) { 9989 /* Interior vertices stay the same */ 9990 newp = vStartNew + (p - vStart); 9991 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9992 } else if ((p >= eStart) && (p < eMax)) { 9993 /* Interior edges add new edges and vertex */ 9994 for (r = 0; r < 2; ++r) { 9995 newp = eStartNew + (p - eStart)*2 + r; 9996 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9997 } 9998 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9999 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10000 } else if ((p >= eMax) && (p < eEnd)) { 10001 /* Hybrid edges stay the same */ 10002 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 10003 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10004 } else if ((p >= fStart) && (p < fMax)) { 10005 /* Interior faces add new faces, edges, and vertex */ 10006 for (r = 0; r < 4; ++r) { 10007 newp = fStartNew + (p - fStart)*4 + r; 10008 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10009 } 10010 for (r = 0; r < 4; ++r) { 10011 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 10012 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10013 } 10014 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 10015 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10016 } else if ((p >= fMax) && (p < fEnd)) { 10017 /* Hybrid faces add new faces and edges */ 10018 for (r = 0; r < 2; ++r) { 10019 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 10020 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10021 } 10022 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 10023 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10024 } else if ((p >= cStart) && (p < cMax)) { 10025 /* Interior cells add new cells, faces, edges, and vertex */ 10026 for (r = 0; r < 8; ++r) { 10027 newp = cStartNew + (p - cStart)*8 + r; 10028 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10029 } 10030 for (r = 0; r < 12; ++r) { 10031 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 10032 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10033 } 10034 for (r = 0; r < 6; ++r) { 10035 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 10036 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10037 } 10038 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 10039 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10040 } else if ((p >= cMax) && (p < cEnd)) { 10041 /* Hybrid cells add new cells, faces, and edges */ 10042 for (r = 0; r < 4; ++r) { 10043 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10044 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10045 } 10046 for (r = 0; r < 4; ++r) { 10047 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 10048 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10049 } 10050 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 10051 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10052 } 10053 break; 10054 default: 10055 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 10056 } 10057 } 10058 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 10059 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 10060 } 10061 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 10062 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 10063 if (0) { 10064 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 10065 } 10066 } 10067 PetscFunctionReturn(0); 10068 } 10069 10070 /* This will only work for interpolated meshes */ 10071 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 10072 { 10073 DM rdm; 10074 PetscInt *depthSize; 10075 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 10076 PetscErrorCode ierr; 10077 10078 PetscFunctionBegin; 10079 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 10080 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 10081 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10082 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 10083 /* Calculate number of new points of each depth */ 10084 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10085 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 10086 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10087 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 10088 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10089 /* Step 1: Set chart */ 10090 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 10091 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 10092 /* Step 2: Set cone/support sizes (automatically stratifies) */ 10093 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10094 /* Step 3: Setup refined DM */ 10095 ierr = DMSetUp(rdm);CHKERRQ(ierr); 10096 /* Step 4: Set cones and supports (automatically symmetrizes) */ 10097 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10098 /* Step 5: Create pointSF */ 10099 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10100 /* Step 6: Create labels */ 10101 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10102 /* Step 7: Set coordinates */ 10103 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10104 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10105 10106 *dmRefined = rdm; 10107 PetscFunctionReturn(0); 10108 } 10109 10110 /*@ 10111 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 10112 10113 Input Parameter: 10114 . dm - The coarse DM 10115 10116 Output Parameter: 10117 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 10118 10119 Level: developer 10120 10121 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 10122 @*/ 10123 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 10124 { 10125 CellRefiner cellRefiner; 10126 PetscInt *depthSize, *fpoints; 10127 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 10128 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 10129 PetscErrorCode ierr; 10130 10131 PetscFunctionBegin; 10132 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10133 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 10134 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 10135 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10136 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10137 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10138 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 10139 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 10140 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 10141 switch (cellRefiner) { 10142 case REFINER_SIMPLEX_1D: 10143 case REFINER_SIMPLEX_2D: 10144 case REFINER_HYBRID_SIMPLEX_2D: 10145 case REFINER_HEX_2D: 10146 case REFINER_HYBRID_HEX_2D: 10147 case REFINER_SIMPLEX_3D: 10148 case REFINER_HYBRID_SIMPLEX_3D: 10149 case REFINER_HEX_3D: 10150 case REFINER_HYBRID_HEX_3D: 10151 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 10152 break; 10153 default: 10154 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[cellRefiner]); 10155 } 10156 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 10157 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10158 PetscFunctionReturn(0); 10159 } 10160 10161 /*@ 10162 DMPlexSetRefinementUniform - Set the flag for uniform refinement 10163 10164 Input Parameters: 10165 + dm - The DM 10166 - refinementUniform - The flag for uniform refinement 10167 10168 Level: developer 10169 10170 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10171 @*/ 10172 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 10173 { 10174 DM_Plex *mesh = (DM_Plex*) dm->data; 10175 10176 PetscFunctionBegin; 10177 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10178 mesh->refinementUniform = refinementUniform; 10179 PetscFunctionReturn(0); 10180 } 10181 10182 /*@ 10183 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 10184 10185 Input Parameter: 10186 . dm - The DM 10187 10188 Output Parameter: 10189 . refinementUniform - The flag for uniform refinement 10190 10191 Level: developer 10192 10193 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10194 @*/ 10195 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 10196 { 10197 DM_Plex *mesh = (DM_Plex*) dm->data; 10198 10199 PetscFunctionBegin; 10200 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10201 PetscValidPointer(refinementUniform, 2); 10202 *refinementUniform = mesh->refinementUniform; 10203 PetscFunctionReturn(0); 10204 } 10205 10206 /*@ 10207 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 10208 10209 Input Parameters: 10210 + dm - The DM 10211 - refinementLimit - The maximum cell volume in the refined mesh 10212 10213 Level: developer 10214 10215 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10216 @*/ 10217 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 10218 { 10219 DM_Plex *mesh = (DM_Plex*) dm->data; 10220 10221 PetscFunctionBegin; 10222 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10223 mesh->refinementLimit = refinementLimit; 10224 PetscFunctionReturn(0); 10225 } 10226 10227 /*@ 10228 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 10229 10230 Input Parameter: 10231 . dm - The DM 10232 10233 Output Parameter: 10234 . refinementLimit - The maximum cell volume in the refined mesh 10235 10236 Level: developer 10237 10238 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10239 @*/ 10240 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 10241 { 10242 DM_Plex *mesh = (DM_Plex*) dm->data; 10243 10244 PetscFunctionBegin; 10245 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10246 PetscValidPointer(refinementLimit, 2); 10247 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 10248 *refinementLimit = mesh->refinementLimit; 10249 PetscFunctionReturn(0); 10250 } 10251 10252 /*@ 10253 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 10254 10255 Input Parameters: 10256 + dm - The DM 10257 - refinementFunc - Function giving the maximum cell volume in the refined mesh 10258 10259 Note: The calling sequence is refinementFunc(coords, limit) 10260 $ coords - Coordinates of the current point, usually a cell centroid 10261 $ limit - The maximum cell volume for a cell containing this point 10262 10263 Level: developer 10264 10265 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10266 @*/ 10267 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 10268 { 10269 DM_Plex *mesh = (DM_Plex*) dm->data; 10270 10271 PetscFunctionBegin; 10272 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10273 mesh->refinementFunc = refinementFunc; 10274 PetscFunctionReturn(0); 10275 } 10276 10277 /*@ 10278 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 10279 10280 Input Parameter: 10281 . dm - The DM 10282 10283 Output Parameter: 10284 . refinementFunc - Function giving the maximum cell volume in the refined mesh 10285 10286 Note: The calling sequence is refinementFunc(coords, limit) 10287 $ coords - Coordinates of the current point, usually a cell centroid 10288 $ limit - The maximum cell volume for a cell containing this point 10289 10290 Level: developer 10291 10292 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10293 @*/ 10294 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 10295 { 10296 DM_Plex *mesh = (DM_Plex*) dm->data; 10297 10298 PetscFunctionBegin; 10299 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10300 PetscValidPointer(refinementFunc, 2); 10301 *refinementFunc = mesh->refinementFunc; 10302 PetscFunctionReturn(0); 10303 } 10304 10305 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 10306 { 10307 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 10308 PetscErrorCode ierr; 10309 10310 PetscFunctionBegin; 10311 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10312 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 10313 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 10314 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 10315 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 10316 switch (dim) { 10317 case 1: 10318 switch (coneSize) { 10319 case 2: 10320 *cellRefiner = REFINER_SIMPLEX_1D; 10321 break; 10322 default: 10323 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10324 } 10325 break; 10326 case 2: 10327 switch (coneSize) { 10328 case 3: 10329 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 10330 else *cellRefiner = REFINER_SIMPLEX_2D; 10331 break; 10332 case 4: 10333 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 10334 else *cellRefiner = REFINER_HEX_2D; 10335 break; 10336 default: 10337 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10338 } 10339 break; 10340 case 3: 10341 switch (coneSize) { 10342 case 4: 10343 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 10344 else *cellRefiner = REFINER_SIMPLEX_3D; 10345 break; 10346 case 5: 10347 if (cMax == 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 10348 else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10349 break; 10350 case 6: 10351 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 10352 else *cellRefiner = REFINER_HEX_3D; 10353 break; 10354 default: 10355 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10356 } 10357 break; 10358 default: 10359 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %D for cell refiner", dim); 10360 } 10361 PetscFunctionReturn(0); 10362 } 10363 10364 PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 10365 { 10366 PetscBool isUniform; 10367 PetscErrorCode ierr; 10368 10369 PetscFunctionBegin; 10370 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10371 if (isUniform) { 10372 CellRefiner cellRefiner; 10373 PetscBool localized; 10374 10375 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10376 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10377 ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 10378 ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr); 10379 ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 10380 if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 10381 } else { 10382 ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 10383 } 10384 PetscFunctionReturn(0); 10385 } 10386 10387 PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 10388 { 10389 DM cdm = dm; 10390 PetscInt r; 10391 PetscBool isUniform, localized; 10392 PetscErrorCode ierr; 10393 10394 PetscFunctionBegin; 10395 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10396 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10397 if (isUniform) { 10398 for (r = 0; r < nlevels; ++r) { 10399 CellRefiner cellRefiner; 10400 10401 ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 10402 ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 10403 ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr); 10404 ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr); 10405 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10406 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10407 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10408 ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 10409 cdm = dmRefined[r]; 10410 } 10411 } else { 10412 for (r = 0; r < nlevels; ++r) { 10413 ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 10414 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10415 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10416 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10417 cdm = dmRefined[r]; 10418 } 10419 } 10420 PetscFunctionReturn(0); 10421 } 10422