Actual source code: plexrefine.c
petsc-3.11.4 2019-09-28
1: #include <petsc/private/dmpleximpl.h>
2: #include <petscsf.h>
4: PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart)
5: {
7: if (cStart) *cStart = 0;
8: if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth];
9: if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
10: if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
11: return(0);
12: }
14: PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd)
15: {
17: if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth];
18: if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
19: if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
20: if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1];
21: return(0);
22: }
24: /* Gets the affine map from the original cell to each subcell */
25: PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
26: {
27: PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ;
28: PetscInt dim, s;
32: switch (refiner) {
33: case REFINER_NOOP: break;
34: case REFINER_SIMPLEX_2D:
35: /*
36: 2
37: |\
38: | \
39: | \
40: | \
41: | C \
42: | \
43: | \
44: 2---1---1
45: |\ D / \
46: | 2 0 \
47: |A \ / B \
48: 0---0-------1
49: */
50: dim = 2;
51: if (numSubcells) *numSubcells = 4;
52: if (v0) {
53: PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);
54: /* A */
55: v[0+0] = -1.0; v[0+1] = -1.0;
56: j[0+0] = 0.5; j[0+1] = 0.0;
57: j[0+2] = 0.0; j[0+3] = 0.5;
58: /* B */
59: v[2+0] = 0.0; v[2+1] = -1.0;
60: j[4+0] = 0.5; j[4+1] = 0.0;
61: j[4+2] = 0.0; j[4+3] = 0.5;
62: /* C */
63: v[4+0] = -1.0; v[4+1] = 0.0;
64: j[8+0] = 0.5; j[8+1] = 0.0;
65: j[8+2] = 0.0; j[8+3] = 0.5;
66: /* D */
67: v[6+0] = 0.0; v[6+1] = -1.0;
68: j[12+0] = 0.0; j[12+1] = -0.5;
69: j[12+2] = 0.5; j[12+3] = 0.5;
70: for (s = 0; s < 4; ++s) {
71: DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
72: DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
73: }
74: }
75: break;
76: case REFINER_HEX_2D:
77: /*
78: 3---------2---------2
79: | | |
80: | D 2 C |
81: | | |
82: 3----3----0----1----1
83: | | |
84: | A 0 B |
85: | | |
86: 0---------0---------1
87: */
88: dim = 2;
89: if (numSubcells) *numSubcells = 4;
90: if (v0) {
91: PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);
92: /* A */
93: v[0+0] = -1.0; v[0+1] = -1.0;
94: j[0+0] = 0.5; j[0+1] = 0.0;
95: j[0+2] = 0.0; j[0+3] = 0.5;
96: /* B */
97: v[2+0] = 0.0; v[2+1] = -1.0;
98: j[4+0] = 0.5; j[4+1] = 0.0;
99: j[4+2] = 0.0; j[4+3] = 0.5;
100: /* C */
101: v[4+0] = 0.0; v[4+1] = 0.0;
102: j[8+0] = 0.5; j[8+1] = 0.0;
103: j[8+2] = 0.0; j[8+3] = 0.5;
104: /* D */
105: v[6+0] = -1.0; v[6+1] = 0.0;
106: j[12+0] = 0.5; j[12+1] = 0.0;
107: j[12+2] = 0.0; j[12+3] = 0.5;
108: for (s = 0; s < 4; ++s) {
109: DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
110: DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
111: }
112: }
113: break;
114: case REFINER_HEX_3D:
115: /*
116: Bottom (viewed from top) Top
117: 1---------2---------2 7---------2---------6
118: | | | | | |
119: | B 2 C | | H 2 G |
120: | | | | | |
121: 3----3----0----1----1 3----3----0----1----1
122: | | | | | |
123: | A 0 D | | E 0 F |
124: | | | | | |
125: 0---------0---------3 4---------0---------5
126: */
127: break;
128: dim = 3;
129: if (numSubcells) *numSubcells = 8;
130: if (v0) {
131: PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);
132: /* A */
133: v[0+0] = -1.0; v[0+1] = -1.0; v[0+2] = -1.0;
134: j[0+0] = 0.5; j[0+1] = 0.0; j[0+2] = 0.0;
135: j[0+3] = 0.0; j[0+4] = 0.5; j[0+5] = 0.0;
136: j[0+6] = 0.0; j[0+7] = 0.0; j[0+8] = 0.5;
137: /* B */
138: v[3+0] = -1.0; v[3+1] = 0.0; v[3+2] = -1.0;
139: j[9+0] = 0.5; j[9+1] = 0.0; j[9+2] = 0.0;
140: j[9+3] = 0.0; j[9+4] = 0.5; j[9+5] = 0.0;
141: j[9+6] = 0.0; j[9+7] = 0.0; j[9+8] = 0.5;
142: /* C */
143: v[6+0] = 0.0; v[6+1] = 0.0; v[6+2] = -1.0;
144: j[18+0] = 0.5; j[18+1] = 0.0; j[18+2] = 0.0;
145: j[18+3] = 0.0; j[18+4] = 0.5; j[18+5] = 0.0;
146: j[18+6] = 0.0; j[18+7] = 0.0; j[18+8] = 0.5;
147: /* D */
148: v[9+0] = 0.0; v[9+1] = -1.0; v[9+2] = -1.0;
149: j[27+0] = 0.5; j[27+1] = 0.0; j[27+2] = 0.0;
150: j[27+3] = 0.0; j[27+4] = 0.5; j[27+5] = 0.0;
151: j[27+6] = 0.0; j[27+7] = 0.0; j[27+8] = 0.5;
152: /* E */
153: v[12+0] = -1.0; v[12+1] = -1.0; v[12+2] = 0.0;
154: j[36+0] = 0.5; j[36+1] = 0.0; j[36+2] = 0.0;
155: j[36+3] = 0.0; j[36+4] = 0.5; j[36+5] = 0.0;
156: j[36+6] = 0.0; j[36+7] = 0.0; j[36+8] = 0.5;
157: /* F */
158: v[15+0] = 0.0; v[15+1] = -1.0; v[15+2] = 0.0;
159: j[45+0] = 0.5; j[45+1] = 0.0; j[45+2] = 0.0;
160: j[45+3] = 0.0; j[45+4] = 0.5; j[45+5] = 0.0;
161: j[45+6] = 0.0; j[45+7] = 0.0; j[45+8] = 0.5;
162: /* G */
163: v[18+0] = 0.0; v[18+1] = 0.0; v[18+2] = 0.0;
164: j[54+0] = 0.5; j[54+1] = 0.0; j[54+2] = 0.0;
165: j[54+3] = 0.0; j[54+4] = 0.5; j[54+5] = 0.0;
166: j[54+6] = 0.0; j[54+7] = 0.0; j[54+8] = 0.5;
167: /* H */
168: v[21+0] = -1.0; v[21+1] = 0.0; v[21+2] = 0.0;
169: j[63+0] = 0.5; j[63+1] = 0.0; j[63+2] = 0.0;
170: j[63+3] = 0.0; j[63+4] = 0.5; j[63+5] = 0.0;
171: j[63+6] = 0.0; j[63+7] = 0.0; j[63+8] = 0.5;
172: for (s = 0; s < 8; ++s) {
173: DMPlex_Det3D_Internal(&detJ, &j[s*dim*dim]);
174: DMPlex_Invert3D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
175: }
176: }
177: default:
178: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
179: }
180: if (v0) {*v0 = v; *jac = j; *invjac = invj;}
181: return(0);
182: }
184: PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
185: {
189: PetscFree3(*v0,*jac,*invjac);
190: return(0);
191: }
193: /* Should this be here or in the DualSpace somehow? */
194: PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside)
195: {
196: PetscReal sum = 0.0;
197: PetscInt d;
200: *inside = PETSC_TRUE;
201: switch (refiner) {
202: case REFINER_NOOP: break;
203: case REFINER_SIMPLEX_2D:
204: for (d = 0; d < 2; ++d) {
205: if (point[d] < -1.0) {*inside = PETSC_FALSE; break;}
206: sum += point[d];
207: }
208: if (sum > 1.0e-10) {*inside = PETSC_FALSE; break;}
209: break;
210: case REFINER_HEX_2D:
211: for (d = 0; d < 2; ++d) if ((point[d] < -1.00000000001) || (point[d] > 1.000000000001)) {*inside = PETSC_FALSE; break;}
212: break;
213: default:
214: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
215: }
216: return(0);
217: }
219: static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
220: {
221: PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
225: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
226: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
227: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
228: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
229: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
230: switch (refiner) {
231: case REFINER_NOOP:
232: break;
233: case REFINER_SIMPLEX_1D:
234: depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */
235: depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */
236: break;
237: case REFINER_SIMPLEX_2D:
238: depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */
239: depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */
240: depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
241: break;
242: case REFINER_HYBRID_SIMPLEX_2D:
243: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
244: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
245: depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */
246: 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 */
247: depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, hybrid cells split into 2 cells */
248: break;
249: case REFINER_SIMPLEX_TO_HEX_2D:
250: depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
251: depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */
252: depthSize[2] = 3*(cEnd - cStart); /* Every cell split into 3 cells */
253: break;
254: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
255: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
256: depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
257: 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 */
258: depthSize[2] = 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every cell split into 3 cells, hybrid cells split in 4 */
259: break;
260: case REFINER_HEX_2D:
261: depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
262: depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */
263: depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
264: break;
265: case REFINER_HYBRID_HEX_2D:
266: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
267: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
268: /* Quadrilateral */
269: depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */
270: depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */
271: depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */
272: /* Segment Prisms */
273: depthSize[0] += 0; /* No hybrid vertices */
274: depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */
275: depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */
276: break;
277: case REFINER_SIMPLEX_3D:
278: depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */
279: 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 */
280: depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */
281: depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */
282: break;
283: case REFINER_HYBRID_SIMPLEX_3D:
284: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
285: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
286: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
287: /* Tetrahedra */
288: depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */
289: 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 */
290: depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */
291: depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */
292: /* Triangular Prisms */
293: depthSize[0] += 0; /* No hybrid vertices */
294: depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */
295: depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */
296: depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */
297: break;
298: case REFINER_SIMPLEX_TO_HEX_3D:
299: depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */
300: 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 */
301: depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */
302: depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
303: break;
304: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
305: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
306: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
307: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
308: /* Tetrahedra */
309: depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every interior edge, face and cell */
310: 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 */
311: depthSize[2] = 3*(fMax - fStart) + 6*(cMax - cStart); /* Every interior face split into 3 faces, 6 faces added for each interior cell */
312: depthSize[3] = 4*(cMax - cStart); /* Every interior cell split into 8 cells */
313: /* Triangular Prisms */
314: depthSize[0] += 0; /* No hybrid vertices */
315: depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and cell */
316: depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */
317: depthSize[3] += 3*(cEnd - cMax); /* Every hybrid cell split into 3 cells */
318: break;
319: case REFINER_HEX_3D:
320: depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
321: 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 */
322: depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */
323: depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */
324: break;
325: case REFINER_HYBRID_HEX_3D:
326: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
327: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
328: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
329: /* Hexahedra */
330: depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
331: 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 */
332: depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */
333: depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */
334: /* Quadrilateral Prisms */
335: depthSize[0] += 0; /* No hybrid vertices */
336: depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
337: depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */
338: depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */
339: break;
340: default:
341: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
342: }
343: return(0);
344: }
346: /* Return triangle edge for orientation o, if it is r for o == 0 */
347: PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
348: return (o < 0 ? 2-(o+r) : o+r)%3;
349: }
350: PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
351: return (o < 0 ? 2-(o+s) : 3+s-o)%3;
352: }
354: /* Return triangle subface for orientation o, if it is r for o == 0 */
355: PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
356: return (o < 0 ? 3-(o+r) : o+r)%3;
357: }
358: PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
359: return (o < 0 ? 3-(o+s) : 3+s-o)%3;
360: }
362: /* Return the interior edge number connecting the midpoints of the triangle edges r
363: and r+1 in the transitive closure for triangle orientation o */
364: PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) {
365: return (o < 0 ? 1-(o+r) : o+r)%3;
366: }
367: PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) {
368: return (o < 0 ? 1-(o+s) : 3+s-o)%3;
369: }
371: /* Return the interior edge number connecting the midpoint of the triangle edge r
372: (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */
373: PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) {
374: return (o < 0 ? 2-(o+r) : o+r)%3;
375: }
376: PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) {
377: return (o < 0 ? 2-(o+s) : 3+s-o)%3;
378: }
380: /* Return quad edge for orientation o, if it is r for o == 0 */
381: PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
382: return (o < 0 ? 3-(o+r) : o+r)%4;
383: }
384: PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
385: return (o < 0 ? 3-(o+s) : 4+s-o)%4;
386: }
388: /* Return quad subface for orientation o, if it is r for o == 0 */
389: PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
390: return (o < 0 ? 4-(o+r) : o+r)%4;
391: }
392: PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
393: return (o < 0 ? 4-(o+s) : 4+s-o)%4;
394: }
396: static PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd)
397: {
398: IS cIS;
402: ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);
403: DMLabelSetStratumIS(label, value, cIS);
404: ISDestroy(&cIS);
405: return(0);
406: }
408: static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
409: {
410: 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;
411: DMLabel depthLabel;
415: DMPlexGetDepth(dm, &depth);
416: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
417: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
418: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
419: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
420: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
421: GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);
422: GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);
423: DMCreateLabel(rdm,"depth");
424: DMPlexGetDepthLabel(rdm,&depthLabel);
425: DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);
426: if (depth > 2) DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);
427: if (depth > 1) DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);
428: if (depth > 0) DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);
429: {
430: DM_Plex *plex = (DM_Plex *) rdm->data;
431: PetscObjectStateGet((PetscObject) depthLabel, &plex->depthState);
432: }
433: if (!refiner) return(0);
434: switch (refiner) {
435: case REFINER_SIMPLEX_1D:
436: /* All cells have 2 vertices */
437: for (c = cStart; c < cEnd; ++c) {
438: for (r = 0; r < 2; ++r) {
439: const PetscInt newp = cStartNew + (c - cStart)*2 + r;
441: DMPlexSetConeSize(rdm, newp, 2);
442: }
443: }
444: /* Old vertices have identical supports */
445: for (v = vStart; v < vEnd; ++v) {
446: const PetscInt newp = vStartNew + (v - vStart);
447: PetscInt size;
449: DMPlexGetSupportSize(dm, v, &size);
450: DMPlexSetSupportSize(rdm, newp, size);
451: }
452: /* Cell vertices have support 2 */
453: for (c = cStart; c < cEnd; ++c) {
454: const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart);
456: DMPlexSetSupportSize(rdm, newp, 2);
457: }
458: break;
459: case REFINER_SIMPLEX_2D:
460: /* All cells have 3 faces */
461: for (c = cStart; c < cEnd; ++c) {
462: for (r = 0; r < 4; ++r) {
463: const PetscInt newp = (c - cStart)*4 + r;
465: DMPlexSetConeSize(rdm, newp, 3);
466: }
467: }
468: /* Split faces have 2 vertices and the same cells as the parent */
469: for (f = fStart; f < fEnd; ++f) {
470: for (r = 0; r < 2; ++r) {
471: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
472: PetscInt size;
474: DMPlexSetConeSize(rdm, newp, 2);
475: DMPlexGetSupportSize(dm, f, &size);
476: DMPlexSetSupportSize(rdm, newp, size);
477: }
478: }
479: /* Interior faces have 2 vertices and 2 cells */
480: for (c = cStart; c < cEnd; ++c) {
481: for (r = 0; r < 3; ++r) {
482: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
484: DMPlexSetConeSize(rdm, newp, 2);
485: DMPlexSetSupportSize(rdm, newp, 2);
486: }
487: }
488: /* Old vertices have identical supports */
489: for (v = vStart; v < vEnd; ++v) {
490: const PetscInt newp = vStartNew + (v - vStart);
491: PetscInt size;
493: DMPlexGetSupportSize(dm, v, &size);
494: DMPlexSetSupportSize(rdm, newp, size);
495: }
496: /* Face vertices have 2 + cells*2 supports */
497: for (f = fStart; f < fEnd; ++f) {
498: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
499: PetscInt size;
501: DMPlexGetSupportSize(dm, f, &size);
502: DMPlexSetSupportSize(rdm, newp, 2 + size*2);
503: }
504: break;
505: case REFINER_SIMPLEX_TO_HEX_2D:
506: /* All cells have 4 faces */
507: for (c = cStart; c < cEnd; ++c) {
508: for (r = 0; r < 3; ++r) {
509: const PetscInt newp = (c - cStart)*3 + r;
511: DMPlexSetConeSize(rdm, newp, 4);
512: }
513: }
514: /* Split faces have 2 vertices and the same cells as the parent */
515: for (f = fStart; f < fEnd; ++f) {
516: for (r = 0; r < 2; ++r) {
517: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
518: PetscInt size;
520: DMPlexSetConeSize(rdm, newp, 2);
521: DMPlexGetSupportSize(dm, f, &size);
522: DMPlexSetSupportSize(rdm, newp, size);
523: }
524: }
525: /* Interior faces have 2 vertices and 2 cells */
526: for (c = cStart; c < cEnd; ++c) {
527: for (r = 0; r < 3; ++r) {
528: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
530: DMPlexSetConeSize(rdm, newp, 2);
531: DMPlexSetSupportSize(rdm, newp, 2);
532: }
533: }
534: /* Old vertices have identical supports */
535: for (v = vStart; v < vEnd; ++v) {
536: const PetscInt newp = vStartNew + (v - vStart);
537: PetscInt size;
539: DMPlexGetSupportSize(dm, v, &size);
540: DMPlexSetSupportSize(rdm, newp, size);
541: }
542: /* Split-face vertices have cells + 2 supports */
543: for (f = fStart; f < fEnd; ++f) {
544: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
545: PetscInt size;
547: DMPlexGetSupportSize(dm, f, &size);
548: DMPlexSetSupportSize(rdm, newp, size + 2);
549: }
550: /* Interior vertices have 3 supports */
551: for (c = cStart; c < cEnd; ++c) {
552: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
554: DMPlexSetSupportSize(rdm, newp, 3);
555: }
556: break;
557: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
558: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
559: /* the mesh is no longer hybrid */
560: cMax = PetscMin(cEnd, cMax);
561: /* All cells have 4 faces */
562: for (c = cStart; c < cMax; ++c) {
563: for (r = 0; r < 3; ++r) {
564: const PetscInt newp = (c - cStart)*3 + r;
566: DMPlexSetConeSize(rdm, newp, 4);
567: }
568: }
569: for (c = cMax; c < cEnd; ++c) {
570: for (r = 0; r < 4; ++r) {
571: const PetscInt newp = (cMax - cStart)*3 + (c - cMax)*4 + r;
573: DMPlexSetConeSize(rdm, newp, 4);
574: }
575: }
576: /* Split faces have 2 vertices and the same cells as the parent */
577: for (f = fStart; f < fEnd; ++f) {
578: for (r = 0; r < 2; ++r) {
579: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
580: PetscInt size;
582: DMPlexSetConeSize(rdm, newp, 2);
583: DMPlexGetSupportSize(dm, f, &size);
584: DMPlexSetSupportSize(rdm, newp, size);
585: }
586: }
587: /* Interior faces have 2 vertices and 2 cells */
588: for (c = cStart; c < cMax; ++c) {
589: for (r = 0; r < 3; ++r) {
590: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
592: DMPlexSetConeSize(rdm, newp, 2);
593: DMPlexSetSupportSize(rdm, newp, 2);
594: }
595: }
596: /* Hybrid interior faces have 2 vertices and 2 cells */
597: for (c = cMax; c < cEnd; ++c) {
598: for (r = 0; r < 4; ++r) {
599: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r;
601: DMPlexSetConeSize(rdm, newp, 2);
602: DMPlexSetSupportSize(rdm, newp, 2);
603: }
604: }
605: /* Old vertices have identical supports */
606: for (v = vStart; v < vEnd; ++v) {
607: const PetscInt newp = vStartNew + (v - vStart);
608: PetscInt size;
610: DMPlexGetSupportSize(dm, v, &size);
611: DMPlexSetSupportSize(rdm, newp, size);
612: }
613: /* Split-face vertices have cells + 2 supports */
614: for (f = fStart; f < fEnd; ++f) {
615: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
616: PetscInt size;
618: DMPlexGetSupportSize(dm, f, &size);
619: DMPlexSetSupportSize(rdm, newp, size + 2);
620: }
621: /* Interior vertices have 3 supports */
622: for (c = cStart; c < cMax; ++c) {
623: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
625: DMPlexSetSupportSize(rdm, newp, 3);
626: }
627: /* Hybrid interior vertices have 4 supports */
628: for (c = cMax; c < cEnd; ++c) {
629: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
631: DMPlexSetSupportSize(rdm, newp, 4);
632: }
633: break;
634: case REFINER_HEX_2D:
635: /* All cells have 4 faces */
636: for (c = cStart; c < cEnd; ++c) {
637: for (r = 0; r < 4; ++r) {
638: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
640: DMPlexSetConeSize(rdm, newp, 4);
641: }
642: }
643: /* Split faces have 2 vertices and the same cells as the parent */
644: for (f = fStart; f < fEnd; ++f) {
645: for (r = 0; r < 2; ++r) {
646: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
647: PetscInt size;
649: DMPlexSetConeSize(rdm, newp, 2);
650: DMPlexGetSupportSize(dm, f, &size);
651: DMPlexSetSupportSize(rdm, newp, size);
652: }
653: }
654: /* Interior faces have 2 vertices and 2 cells */
655: for (c = cStart; c < cEnd; ++c) {
656: for (r = 0; r < 4; ++r) {
657: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
659: DMPlexSetConeSize(rdm, newp, 2);
660: DMPlexSetSupportSize(rdm, newp, 2);
661: }
662: }
663: /* Old vertices have identical supports */
664: for (v = vStart; v < vEnd; ++v) {
665: const PetscInt newp = vStartNew + (v - vStart);
666: PetscInt size;
668: DMPlexGetSupportSize(dm, v, &size);
669: DMPlexSetSupportSize(rdm, newp, size);
670: }
671: /* Face vertices have 2 + cells supports */
672: for (f = fStart; f < fEnd; ++f) {
673: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
674: PetscInt size;
676: DMPlexGetSupportSize(dm, f, &size);
677: DMPlexSetSupportSize(rdm, newp, 2 + size);
678: }
679: /* Cell vertices have 4 supports */
680: for (c = cStart; c < cEnd; ++c) {
681: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
683: DMPlexSetSupportSize(rdm, newp, 4);
684: }
685: break;
686: case REFINER_HYBRID_SIMPLEX_2D:
687: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
688: cMax = PetscMin(cEnd, cMax);
689: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
690: fMax = PetscMin(fEnd, fMax);
691: DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);
692: /* Interior cells have 3 faces */
693: for (c = cStart; c < cMax; ++c) {
694: for (r = 0; r < 4; ++r) {
695: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
697: DMPlexSetConeSize(rdm, newp, 3);
698: }
699: }
700: /* Hybrid cells have 4 faces */
701: for (c = cMax; c < cEnd; ++c) {
702: for (r = 0; r < 2; ++r) {
703: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
705: DMPlexSetConeSize(rdm, newp, 4);
706: }
707: }
708: /* Interior split faces have 2 vertices and the same cells as the parent */
709: for (f = fStart; f < fMax; ++f) {
710: for (r = 0; r < 2; ++r) {
711: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
712: PetscInt size;
714: DMPlexSetConeSize(rdm, newp, 2);
715: DMPlexGetSupportSize(dm, f, &size);
716: DMPlexSetSupportSize(rdm, newp, size);
717: }
718: }
719: /* Interior cell faces have 2 vertices and 2 cells */
720: for (c = cStart; c < cMax; ++c) {
721: for (r = 0; r < 3; ++r) {
722: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
724: DMPlexSetConeSize(rdm, newp, 2);
725: DMPlexSetSupportSize(rdm, newp, 2);
726: }
727: }
728: /* Hybrid faces have 2 vertices and the same cells */
729: for (f = fMax; f < fEnd; ++f) {
730: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
731: PetscInt size;
733: DMPlexSetConeSize(rdm, newp, 2);
734: DMPlexGetSupportSize(dm, f, &size);
735: DMPlexSetSupportSize(rdm, newp, size);
736: }
737: /* Hybrid cell faces have 2 vertices and 2 cells */
738: for (c = cMax; c < cEnd; ++c) {
739: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
741: DMPlexSetConeSize(rdm, newp, 2);
742: DMPlexSetSupportSize(rdm, newp, 2);
743: }
744: /* Old vertices have identical supports */
745: for (v = vStart; v < vEnd; ++v) {
746: const PetscInt newp = vStartNew + (v - vStart);
747: PetscInt size;
749: DMPlexGetSupportSize(dm, v, &size);
750: DMPlexSetSupportSize(rdm, newp, size);
751: }
752: /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
753: for (f = fStart; f < fMax; ++f) {
754: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
755: const PetscInt *support;
756: PetscInt size, newSize = 2, s;
758: DMPlexGetSupportSize(dm, f, &size);
759: DMPlexGetSupport(dm, f, &support);
760: for (s = 0; s < size; ++s) {
761: if (support[s] >= cMax) newSize += 1;
762: else newSize += 2;
763: }
764: DMPlexSetSupportSize(rdm, newp, newSize);
765: }
766: break;
767: case REFINER_HYBRID_HEX_2D:
768: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
769: cMax = PetscMin(cEnd, cMax);
770: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
771: fMax = PetscMin(fEnd, fMax);
772: DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);
773: /* Interior cells have 4 faces */
774: for (c = cStart; c < cMax; ++c) {
775: for (r = 0; r < 4; ++r) {
776: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
778: DMPlexSetConeSize(rdm, newp, 4);
779: }
780: }
781: /* Hybrid cells have 4 faces */
782: for (c = cMax; c < cEnd; ++c) {
783: for (r = 0; r < 2; ++r) {
784: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
786: DMPlexSetConeSize(rdm, newp, 4);
787: }
788: }
789: /* Interior split faces have 2 vertices and the same cells as the parent */
790: for (f = fStart; f < fMax; ++f) {
791: for (r = 0; r < 2; ++r) {
792: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
793: PetscInt size;
795: DMPlexSetConeSize(rdm, newp, 2);
796: DMPlexGetSupportSize(dm, f, &size);
797: DMPlexSetSupportSize(rdm, newp, size);
798: }
799: }
800: /* Interior cell faces have 2 vertices and 2 cells */
801: for (c = cStart; c < cMax; ++c) {
802: for (r = 0; r < 4; ++r) {
803: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
805: DMPlexSetConeSize(rdm, newp, 2);
806: DMPlexSetSupportSize(rdm, newp, 2);
807: }
808: }
809: /* Hybrid faces have 2 vertices and the same cells */
810: for (f = fMax; f < fEnd; ++f) {
811: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
812: PetscInt size;
814: DMPlexSetConeSize(rdm, newp, 2);
815: DMPlexGetSupportSize(dm, f, &size);
816: DMPlexSetSupportSize(rdm, newp, size);
817: }
818: /* Hybrid cell faces have 2 vertices and 2 cells */
819: for (c = cMax; c < cEnd; ++c) {
820: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
822: DMPlexSetConeSize(rdm, newp, 2);
823: DMPlexSetSupportSize(rdm, newp, 2);
824: }
825: /* Old vertices have identical supports */
826: for (v = vStart; v < vEnd; ++v) {
827: const PetscInt newp = vStartNew + (v - vStart);
828: PetscInt size;
830: DMPlexGetSupportSize(dm, v, &size);
831: DMPlexSetSupportSize(rdm, newp, size);
832: }
833: /* Face vertices have 2 + cells supports */
834: for (f = fStart; f < fMax; ++f) {
835: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
836: PetscInt size;
838: DMPlexGetSupportSize(dm, f, &size);
839: DMPlexSetSupportSize(rdm, newp, 2 + size);
840: }
841: /* Cell vertices have 4 supports */
842: for (c = cStart; c < cMax; ++c) {
843: const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
845: DMPlexSetSupportSize(rdm, newp, 4);
846: }
847: break;
848: case REFINER_SIMPLEX_3D:
849: /* All cells have 4 faces */
850: for (c = cStart; c < cEnd; ++c) {
851: for (r = 0; r < 8; ++r) {
852: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
854: DMPlexSetConeSize(rdm, newp, 4);
855: }
856: }
857: /* Split faces have 3 edges and the same cells as the parent */
858: for (f = fStart; f < fEnd; ++f) {
859: for (r = 0; r < 4; ++r) {
860: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
861: PetscInt size;
863: DMPlexSetConeSize(rdm, newp, 3);
864: DMPlexGetSupportSize(dm, f, &size);
865: DMPlexSetSupportSize(rdm, newp, size);
866: }
867: }
868: /* Interior cell faces have 3 edges and 2 cells */
869: for (c = cStart; c < cEnd; ++c) {
870: for (r = 0; r < 8; ++r) {
871: const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
873: DMPlexSetConeSize(rdm, newp, 3);
874: DMPlexSetSupportSize(rdm, newp, 2);
875: }
876: }
877: /* Split edges have 2 vertices and the same faces */
878: for (e = eStart; e < eEnd; ++e) {
879: for (r = 0; r < 2; ++r) {
880: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
881: PetscInt size;
883: DMPlexSetConeSize(rdm, newp, 2);
884: DMPlexGetSupportSize(dm, e, &size);
885: DMPlexSetSupportSize(rdm, newp, size);
886: }
887: }
888: /* Face edges have 2 vertices and 2+cells*(1/2) faces */
889: for (f = fStart; f < fEnd; ++f) {
890: for (r = 0; r < 3; ++r) {
891: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
892: const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
893: PetscInt coneSize, c, supportSize, s, er, intFaces = 0;
895: DMPlexSetConeSize(rdm, newp, 2);
896: DMPlexGetSupportSize(dm, f, &supportSize);
897: DMPlexGetSupport(dm, f, &support);
898: for (s = 0; s < supportSize; ++s) {
899: DMPlexGetConeSize(dm, support[s], &coneSize);
900: DMPlexGetCone(dm, support[s], &cone);
901: DMPlexGetConeOrientation(dm, support[s], &ornt);
902: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
903: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
904: er = GetTriMidEdgeInverse_Static(ornt[c], r);
905: if (er == eint[c]) {
906: intFaces += 1;
907: } else {
908: intFaces += 2;
909: }
910: }
911: DMPlexSetSupportSize(rdm, newp, 2+intFaces);
912: }
913: }
914: /* Interior cell edges have 2 vertices and 4 faces */
915: for (c = cStart; c < cEnd; ++c) {
916: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
918: DMPlexSetConeSize(rdm, newp, 2);
919: DMPlexSetSupportSize(rdm, newp, 4);
920: }
921: /* Old vertices have identical supports */
922: for (v = vStart; v < vEnd; ++v) {
923: const PetscInt newp = vStartNew + (v - vStart);
924: PetscInt size;
926: DMPlexGetSupportSize(dm, v, &size);
927: DMPlexSetSupportSize(rdm, newp, size);
928: }
929: /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
930: for (e = eStart; e < eEnd; ++e) {
931: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
932: PetscInt size, *star = NULL, starSize, s, cellSize = 0;
934: DMPlexGetSupportSize(dm, e, &size);
935: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
936: for (s = 0; s < starSize*2; s += 2) {
937: const PetscInt *cone, *ornt;
938: PetscInt e01, e23;
940: if ((star[s] >= cStart) && (star[s] < cEnd)) {
941: /* Check edge 0-1 */
942: DMPlexGetCone(dm, star[s], &cone);
943: DMPlexGetConeOrientation(dm, star[s], &ornt);
944: DMPlexGetCone(dm, cone[0], &cone);
945: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
946: /* Check edge 2-3 */
947: DMPlexGetCone(dm, star[s], &cone);
948: DMPlexGetConeOrientation(dm, star[s], &ornt);
949: DMPlexGetCone(dm, cone[2], &cone);
950: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
951: if ((e01 == e) || (e23 == e)) ++cellSize;
952: }
953: }
954: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
955: DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);
956: }
957: break;
958: case REFINER_HYBRID_SIMPLEX_3D:
959: DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
960: eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);
961: /* Interior cells have 4 faces */
962: for (c = cStart; c < cMax; ++c) {
963: for (r = 0; r < 8; ++r) {
964: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
966: DMPlexSetConeSize(rdm, newp, 4);
967: }
968: }
969: /* Hybrid cells have 5 faces */
970: for (c = cMax; c < cEnd; ++c) {
971: for (r = 0; r < 4; ++r) {
972: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
974: DMPlexSetConeSize(rdm, newp, 5);
975: }
976: }
977: /* Interior split faces have 3 edges and the same cells as the parent */
978: for (f = fStart; f < fMax; ++f) {
979: for (r = 0; r < 4; ++r) {
980: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
981: PetscInt size;
983: DMPlexSetConeSize(rdm, newp, 3);
984: DMPlexGetSupportSize(dm, f, &size);
985: DMPlexSetSupportSize(rdm, newp, size);
986: }
987: }
988: /* Interior cell faces have 3 edges and 2 cells */
989: for (c = cStart; c < cMax; ++c) {
990: for (r = 0; r < 8; ++r) {
991: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
993: DMPlexSetConeSize(rdm, newp, 3);
994: DMPlexSetSupportSize(rdm, newp, 2);
995: }
996: }
997: /* Hybrid split faces have 4 edges and the same cells as the parent */
998: for (f = fMax; f < fEnd; ++f) {
999: for (r = 0; r < 2; ++r) {
1000: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
1001: PetscInt size;
1003: DMPlexSetConeSize(rdm, newp, 4);
1004: DMPlexGetSupportSize(dm, f, &size);
1005: DMPlexSetSupportSize(rdm, newp, size);
1006: }
1007: }
1008: /* Hybrid cells faces have 4 edges and 2 cells */
1009: for (c = cMax; c < cEnd; ++c) {
1010: for (r = 0; r < 3; ++r) {
1011: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
1013: DMPlexSetConeSize(rdm, newp, 4);
1014: DMPlexSetSupportSize(rdm, newp, 2);
1015: }
1016: }
1017: /* Interior split edges have 2 vertices and the same faces */
1018: for (e = eStart; e < eMax; ++e) {
1019: for (r = 0; r < 2; ++r) {
1020: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1021: PetscInt size;
1023: DMPlexSetConeSize(rdm, newp, 2);
1024: DMPlexGetSupportSize(dm, e, &size);
1025: DMPlexSetSupportSize(rdm, newp, size);
1026: }
1027: }
1028: /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
1029: for (f = fStart; f < fMax; ++f) {
1030: for (r = 0; r < 3; ++r) {
1031: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
1032: const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
1033: PetscInt coneSize, c, supportSize, s, er, intFaces = 0;
1035: DMPlexSetConeSize(rdm, newp, 2);
1036: DMPlexGetSupportSize(dm, f, &supportSize);
1037: DMPlexGetSupport(dm, f, &support);
1038: for (s = 0; s < supportSize; ++s) {
1039: DMPlexGetConeSize(dm, support[s], &coneSize);
1040: DMPlexGetCone(dm, support[s], &cone);
1041: DMPlexGetConeOrientation(dm, support[s], &ornt);
1042: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
1043: if (support[s] < cMax) {
1044: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
1045: er = GetTriMidEdgeInverse_Static(ornt[c], r);
1046: if (er == eint[c]) {
1047: intFaces += 1;
1048: } else {
1049: intFaces += 2;
1050: }
1051: } else {
1052: intFaces += 1;
1053: }
1054: }
1055: DMPlexSetSupportSize(rdm, newp, 2+intFaces);
1056: }
1057: }
1058: /* Interior cell edges have 2 vertices and 4 faces */
1059: for (c = cStart; c < cMax; ++c) {
1060: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
1062: DMPlexSetConeSize(rdm, newp, 2);
1063: DMPlexSetSupportSize(rdm, newp, 4);
1064: }
1065: /* Hybrid edges have 2 vertices and the same faces */
1066: for (e = eMax; e < eEnd; ++e) {
1067: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
1068: PetscInt size;
1070: DMPlexSetConeSize(rdm, newp, 2);
1071: DMPlexGetSupportSize(dm, e, &size);
1072: DMPlexSetSupportSize(rdm, newp, size);
1073: }
1074: /* Hybrid face edges have 2 vertices and 2+2*cells faces */
1075: for (f = fMax; f < fEnd; ++f) {
1076: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
1077: PetscInt size;
1079: DMPlexSetConeSize(rdm, newp, 2);
1080: DMPlexGetSupportSize(dm, f, &size);
1081: DMPlexSetSupportSize(rdm, newp, 2+2*size);
1082: }
1083: /* Interior vertices have identical supports */
1084: for (v = vStart; v < vEnd; ++v) {
1085: const PetscInt newp = vStartNew + (v - vStart);
1086: PetscInt size;
1088: DMPlexGetSupportSize(dm, v, &size);
1089: DMPlexSetSupportSize(rdm, newp, size);
1090: }
1091: /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
1092: for (e = eStart; e < eMax; ++e) {
1093: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1094: const PetscInt *support;
1095: PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
1097: DMPlexGetSupportSize(dm, e, &size);
1098: DMPlexGetSupport(dm, e, &support);
1099: for (s = 0; s < size; ++s) {
1100: if (support[s] < fMax) faceSize += 2;
1101: else faceSize += 1;
1102: }
1103: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
1104: for (s = 0; s < starSize*2; s += 2) {
1105: const PetscInt *cone, *ornt;
1106: PetscInt e01, e23;
1108: if ((star[s] >= cStart) && (star[s] < cMax)) {
1109: /* Check edge 0-1 */
1110: DMPlexGetCone(dm, star[s], &cone);
1111: DMPlexGetConeOrientation(dm, star[s], &ornt);
1112: DMPlexGetCone(dm, cone[0], &cone);
1113: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
1114: /* Check edge 2-3 */
1115: DMPlexGetCone(dm, star[s], &cone);
1116: DMPlexGetConeOrientation(dm, star[s], &ornt);
1117: DMPlexGetCone(dm, cone[2], &cone);
1118: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
1119: if ((e01 == e) || (e23 == e)) ++cellSize;
1120: }
1121: }
1122: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
1123: DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);
1124: }
1125: break;
1126: case REFINER_SIMPLEX_TO_HEX_3D:
1127: /* All cells have 6 faces */
1128: for (c = cStart; c < cEnd; ++c) {
1129: for (r = 0; r < 4; ++r) {
1130: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
1132: DMPlexSetConeSize(rdm, newp, 6);
1133: }
1134: }
1135: /* Split faces have 4 edges and the same cells as the parent */
1136: for (f = fStart; f < fEnd; ++f) {
1137: for (r = 0; r < 3; ++r) {
1138: const PetscInt newp = fStartNew + (f - fStart)*3 + r;
1139: PetscInt size;
1141: DMPlexSetConeSize(rdm, newp, 4);
1142: DMPlexGetSupportSize(dm, f, &size);
1143: DMPlexSetSupportSize(rdm, newp, size);
1144: }
1145: }
1146: /* Interior cell faces have 4 edges and 2 cells */
1147: for (c = cStart; c < cEnd; ++c) {
1148: for (r = 0; r < 6; ++r) {
1149: const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r;
1151: DMPlexSetConeSize(rdm, newp, 4);
1152: DMPlexSetSupportSize(rdm, newp, 2);
1153: }
1154: }
1155: /* Split edges have 2 vertices and the same faces */
1156: for (e = eStart; e < eEnd; ++e) {
1157: for (r = 0; r < 2; ++r) {
1158: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1159: PetscInt size;
1161: DMPlexSetConeSize(rdm, newp, 2);
1162: DMPlexGetSupportSize(dm, e, &size);
1163: DMPlexSetSupportSize(rdm, newp, size);
1164: }
1165: }
1166: /* Face edges have 2 vertices and 2 + cell faces supports */
1167: for (f = fStart; f < fEnd; ++f) {
1168: for (r = 0; r < 3; ++r) {
1169: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
1170: PetscInt size;
1172: DMPlexSetConeSize(rdm, newp, 2);
1173: DMPlexGetSupportSize(dm, f, &size);
1174: DMPlexSetSupportSize(rdm, newp, 2+size);
1175: }
1176: }
1177: /* Interior cell edges have 2 vertices and 3 faces */
1178: for (c = cStart; c < cEnd; ++c) {
1179: for (r = 0; r < 4; ++r) {
1180: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
1182: DMPlexSetConeSize(rdm, newp, 2);
1183: DMPlexSetSupportSize(rdm, newp, 3);
1184: }
1185: }
1186: /* Old vertices have identical supports */
1187: for (v = vStart; v < vEnd; ++v) {
1188: const PetscInt newp = vStartNew + (v - vStart);
1189: PetscInt size;
1191: DMPlexGetSupportSize(dm, v, &size);
1192: DMPlexSetSupportSize(rdm, newp, size);
1193: }
1194: /* Edge vertices have 2 + faces supports */
1195: for (e = eStart; e < eEnd; ++e) {
1196: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1197: PetscInt size;
1199: DMPlexGetSupportSize(dm, e, &size);
1200: DMPlexSetSupportSize(rdm, newp, 2 + size);
1201: }
1202: /* Face vertices have 3 + cells supports */
1203: for (f = fStart; f < fEnd; ++f) {
1204: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
1205: PetscInt size;
1207: DMPlexGetSupportSize(dm, f, &size);
1208: DMPlexSetSupportSize(rdm, newp, 3 + size);
1209: }
1210: /* Interior cell vertices have 4 supports */
1211: for (c = cStart; c < cEnd; ++c) {
1212: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart;
1214: DMPlexSetSupportSize(rdm, newp, 4);
1215: }
1216: break;
1217: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
1218: /* the mesh is no longer hybrid */
1219: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1220: cMax = PetscMin(cEnd, cMax);
1221: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
1222: fMax = PetscMin(fEnd, fMax);
1223: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
1224: eMax = PetscMin(eEnd, eMax);
1225: /* All cells have 6 faces */
1226: for (c = cStart; c < cMax; ++c) {
1227: for (r = 0; r < 4; ++r) {
1228: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
1230: DMPlexSetConeSize(rdm, newp, 6);
1231: }
1232: }
1233: for (c = cMax; c < cEnd; ++c) {
1234: for (r = 0; r < 3; ++r) {
1235: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + r;
1237: DMPlexSetConeSize(rdm, newp, 6);
1238: }
1239: }
1240: /* Interior split faces have 4 edges and the same cells as the parent */
1241: for (f = fStart; f < fMax; ++f) {
1242: for (r = 0; r < 3; ++r) {
1243: const PetscInt newp = fStartNew + (f - fStart)*3 + r;
1244: PetscInt size;
1246: DMPlexSetConeSize(rdm, newp, 4);
1247: DMPlexGetSupportSize(dm, f, &size);
1248: DMPlexSetSupportSize(rdm, newp, size);
1249: }
1250: }
1251: /* Interior cell faces have 4 edges and 2 cells */
1252: for (c = cStart; c < cMax; ++c) {
1253: for (r = 0; r < 6; ++r) {
1254: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + r;
1256: DMPlexSetConeSize(rdm, newp, 4);
1257: DMPlexSetSupportSize(rdm, newp, 2);
1258: }
1259: }
1260: /* Hybrid split faces have 4 edges and the same cells as the parent */
1261: for (f = fMax; f < fEnd; ++f) {
1262: for (r = 0; r < 2; ++r) {
1263: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2 + r;
1264: PetscInt size;
1266: DMPlexSetConeSize(rdm, newp, 4);
1267: DMPlexGetSupportSize(dm, f, &size);
1268: DMPlexSetSupportSize(rdm, newp, size);
1269: }
1270: }
1271: /* Hybrid cell faces have 4 edges and 2 cells */
1272: for (c = cMax; c < cEnd; ++c) {
1273: for (r = 0; r < 3; ++r) {
1274: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
1276: DMPlexSetConeSize(rdm, newp, 4);
1277: DMPlexSetSupportSize(rdm, newp, 2);
1278: }
1279: }
1280: /* Interior split edges have 2 vertices and the same faces */
1281: for (e = eStart; e < eMax; ++e) {
1282: for (r = 0; r < 2; ++r) {
1283: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1284: PetscInt size;
1286: DMPlexSetConeSize(rdm, newp, 2);
1287: DMPlexGetSupportSize(dm, e, &size);
1288: DMPlexSetSupportSize(rdm, newp, size);
1289: }
1290: }
1291: /* Interior face edges have 2 vertices and 2 + cell faces supports */
1292: for (f = fStart; f < fMax; ++f) {
1293: for (r = 0; r < 3; ++r) {
1294: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
1295: PetscInt size;
1297: DMPlexSetConeSize(rdm, newp, 2);
1298: DMPlexGetSupportSize(dm, f, &size);
1299: DMPlexSetSupportSize(rdm, newp, 2+size);
1300: }
1301: }
1302: /* Interior cell edges have 2 vertices and 3 faces */
1303: for (c = cStart; c < cMax; ++c) {
1304: for (r = 0; r < 4; ++r) {
1305: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r;
1307: DMPlexSetConeSize(rdm, newp, 2);
1308: DMPlexSetSupportSize(rdm, newp, 3);
1309: }
1310: }
1311: /* Hybrid edges have 2 vertices and the same faces */
1312: for (e = eMax; e < eEnd; ++e) {
1313: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax);
1314: PetscInt size;
1316: DMPlexSetConeSize(rdm, newp, 2);
1317: DMPlexGetSupportSize(dm, e, &size);
1318: DMPlexSetSupportSize(rdm, newp, size);
1319: }
1320: /* Hybrid face edges have 2 vertices and 2+cells faces */
1321: for (f = fMax; f < fEnd; ++f) {
1322: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax);
1323: PetscInt size;
1325: DMPlexSetConeSize(rdm, newp, 2);
1326: DMPlexGetSupportSize(dm, f, &size);
1327: DMPlexSetSupportSize(rdm, newp, 2+size);
1328: }
1329: /* Hybrid cell edges have 2 vertices and 3 faces */
1330: for (c = cMax; c < cEnd; ++c) {
1331: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
1333: DMPlexSetConeSize(rdm, newp, 2);
1334: DMPlexSetSupportSize(rdm, newp, 3);
1335: }
1336: /* Old vertices have identical supports */
1337: for (v = vStart; v < vEnd; ++v) {
1338: const PetscInt newp = vStartNew + (v - vStart);
1339: PetscInt size;
1341: DMPlexGetSupportSize(dm, v, &size);
1342: DMPlexSetSupportSize(rdm, newp, size);
1343: }
1344: /* Interior edge vertices have 2 + faces supports */
1345: for (e = eStart; e < eMax; ++e) {
1346: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1347: PetscInt size;
1349: DMPlexGetSupportSize(dm, e, &size);
1350: DMPlexSetSupportSize(rdm, newp, 2 + size);
1351: }
1352: /* Interior face vertices have 3 + cells supports */
1353: for (f = fStart; f < fMax; ++f) {
1354: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart;
1355: PetscInt size;
1357: DMPlexGetSupportSize(dm, f, &size);
1358: DMPlexSetSupportSize(rdm, newp, 3 + size);
1359: }
1360: /* Interior cell vertices have 4 supports */
1361: for (c = cStart; c < cMax; ++c) {
1362: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart;
1364: DMPlexSetSupportSize(rdm, newp, 4);
1365: }
1366: break;
1367: case REFINER_HEX_3D:
1368: /* All cells have 6 faces */
1369: for (c = cStart; c < cEnd; ++c) {
1370: for (r = 0; r < 8; ++r) {
1371: const PetscInt newp = (c - cStart)*8 + r;
1373: DMPlexSetConeSize(rdm, newp, 6);
1374: }
1375: }
1376: /* Split faces have 4 edges and the same cells as the parent */
1377: for (f = fStart; f < fEnd; ++f) {
1378: for (r = 0; r < 4; ++r) {
1379: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
1380: PetscInt size;
1382: DMPlexSetConeSize(rdm, newp, 4);
1383: DMPlexGetSupportSize(dm, f, &size);
1384: DMPlexSetSupportSize(rdm, newp, size);
1385: }
1386: }
1387: /* Interior faces have 4 edges and 2 cells */
1388: for (c = cStart; c < cEnd; ++c) {
1389: for (r = 0; r < 12; ++r) {
1390: const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
1392: DMPlexSetConeSize(rdm, newp, 4);
1393: DMPlexSetSupportSize(rdm, newp, 2);
1394: }
1395: }
1396: /* Split edges have 2 vertices and the same faces as the parent */
1397: for (e = eStart; e < eEnd; ++e) {
1398: for (r = 0; r < 2; ++r) {
1399: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1400: PetscInt size;
1402: DMPlexSetConeSize(rdm, newp, 2);
1403: DMPlexGetSupportSize(dm, e, &size);
1404: DMPlexSetSupportSize(rdm, newp, size);
1405: }
1406: }
1407: /* Face edges have 2 vertices and 2+cells faces */
1408: for (f = fStart; f < fEnd; ++f) {
1409: for (r = 0; r < 4; ++r) {
1410: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
1411: PetscInt size;
1413: DMPlexSetConeSize(rdm, newp, 2);
1414: DMPlexGetSupportSize(dm, f, &size);
1415: DMPlexSetSupportSize(rdm, newp, 2+size);
1416: }
1417: }
1418: /* Cell edges have 2 vertices and 4 faces */
1419: for (c = cStart; c < cEnd; ++c) {
1420: for (r = 0; r < 6; ++r) {
1421: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
1423: DMPlexSetConeSize(rdm, newp, 2);
1424: DMPlexSetSupportSize(rdm, newp, 4);
1425: }
1426: }
1427: /* Old vertices have identical supports */
1428: for (v = vStart; v < vEnd; ++v) {
1429: const PetscInt newp = vStartNew + (v - vStart);
1430: PetscInt size;
1432: DMPlexGetSupportSize(dm, v, &size);
1433: DMPlexSetSupportSize(rdm, newp, size);
1434: }
1435: /* Edge vertices have 2 + faces supports */
1436: for (e = eStart; e < eEnd; ++e) {
1437: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1438: PetscInt size;
1440: DMPlexGetSupportSize(dm, e, &size);
1441: DMPlexSetSupportSize(rdm, newp, 2 + size);
1442: }
1443: /* Face vertices have 4 + cells supports */
1444: for (f = fStart; f < fEnd; ++f) {
1445: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
1446: PetscInt size;
1448: DMPlexGetSupportSize(dm, f, &size);
1449: DMPlexSetSupportSize(rdm, newp, 4 + size);
1450: }
1451: /* Cell vertices have 6 supports */
1452: for (c = cStart; c < cEnd; ++c) {
1453: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
1455: DMPlexSetSupportSize(rdm, newp, 6);
1456: }
1457: break;
1458: case REFINER_HYBRID_HEX_3D:
1459: DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
1460: eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);
1461: /* Interior cells have 6 faces */
1462: for (c = cStart; c < cMax; ++c) {
1463: for (r = 0; r < 8; ++r) {
1464: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
1466: DMPlexSetConeSize(rdm, newp, 6);
1467: }
1468: }
1469: /* Hybrid cells have 6 faces */
1470: for (c = cMax; c < cEnd; ++c) {
1471: for (r = 0; r < 4; ++r) {
1472: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
1474: DMPlexSetConeSize(rdm, newp, 6);
1475: }
1476: }
1477: /* Interior split faces have 4 edges and the same cells as the parent */
1478: for (f = fStart; f < fMax; ++f) {
1479: for (r = 0; r < 4; ++r) {
1480: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
1481: PetscInt size;
1483: DMPlexSetConeSize(rdm, newp, 4);
1484: DMPlexGetSupportSize(dm, f, &size);
1485: DMPlexSetSupportSize(rdm, newp, size);
1486: }
1487: }
1488: /* Interior cell faces have 4 edges and 2 cells */
1489: for (c = cStart; c < cMax; ++c) {
1490: for (r = 0; r < 12; ++r) {
1491: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
1493: DMPlexSetConeSize(rdm, newp, 4);
1494: DMPlexSetSupportSize(rdm, newp, 2);
1495: }
1496: }
1497: /* Hybrid split faces have 4 edges and the same cells as the parent */
1498: for (f = fMax; f < fEnd; ++f) {
1499: for (r = 0; r < 2; ++r) {
1500: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
1501: PetscInt size;
1503: DMPlexSetConeSize(rdm, newp, 4);
1504: DMPlexGetSupportSize(dm, f, &size);
1505: DMPlexSetSupportSize(rdm, newp, size);
1506: }
1507: }
1508: /* Hybrid cells faces have 4 edges and 2 cells */
1509: for (c = cMax; c < cEnd; ++c) {
1510: for (r = 0; r < 4; ++r) {
1511: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
1513: DMPlexSetConeSize(rdm, newp, 4);
1514: DMPlexSetSupportSize(rdm, newp, 2);
1515: }
1516: }
1517: /* Interior split edges have 2 vertices and the same faces as the parent */
1518: for (e = eStart; e < eMax; ++e) {
1519: for (r = 0; r < 2; ++r) {
1520: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1521: PetscInt size;
1523: DMPlexSetConeSize(rdm, newp, 2);
1524: DMPlexGetSupportSize(dm, e, &size);
1525: DMPlexSetSupportSize(rdm, newp, size);
1526: }
1527: }
1528: /* Interior face edges have 2 vertices and 2+cells faces */
1529: for (f = fStart; f < fMax; ++f) {
1530: for (r = 0; r < 4; ++r) {
1531: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
1532: PetscInt size;
1534: DMPlexSetConeSize(rdm, newp, 2);
1535: DMPlexGetSupportSize(dm, f, &size);
1536: DMPlexSetSupportSize(rdm, newp, 2+size);
1537: }
1538: }
1539: /* Interior cell edges have 2 vertices and 4 faces */
1540: for (c = cStart; c < cMax; ++c) {
1541: for (r = 0; r < 6; ++r) {
1542: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
1544: DMPlexSetConeSize(rdm, newp, 2);
1545: DMPlexSetSupportSize(rdm, newp, 4);
1546: }
1547: }
1548: /* Hybrid edges have 2 vertices and the same faces */
1549: for (e = eMax; e < eEnd; ++e) {
1550: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
1551: PetscInt size;
1553: DMPlexSetConeSize(rdm, newp, 2);
1554: DMPlexGetSupportSize(dm, e, &size);
1555: DMPlexSetSupportSize(rdm, newp, size);
1556: }
1557: /* Hybrid face edges have 2 vertices and 2+cells faces */
1558: for (f = fMax; f < fEnd; ++f) {
1559: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
1560: PetscInt size;
1562: DMPlexSetConeSize(rdm, newp, 2);
1563: DMPlexGetSupportSize(dm, f, &size);
1564: DMPlexSetSupportSize(rdm, newp, 2+size);
1565: }
1566: /* Hybrid cell edges have 2 vertices and 4 faces */
1567: for (c = cMax; c < cEnd; ++c) {
1568: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
1570: DMPlexSetConeSize(rdm, newp, 2);
1571: DMPlexSetSupportSize(rdm, newp, 4);
1572: }
1573: /* Interior vertices have identical supports */
1574: for (v = vStart; v < vEnd; ++v) {
1575: const PetscInt newp = vStartNew + (v - vStart);
1576: PetscInt size;
1578: DMPlexGetSupportSize(dm, v, &size);
1579: DMPlexSetSupportSize(rdm, newp, size);
1580: }
1581: /* Interior edge vertices have 2 + faces supports */
1582: for (e = eStart; e < eMax; ++e) {
1583: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1584: PetscInt size;
1586: DMPlexGetSupportSize(dm, e, &size);
1587: DMPlexSetSupportSize(rdm, newp, 2 + size);
1588: }
1589: /* Interior face vertices have 4 + cells supports */
1590: for (f = fStart; f < fMax; ++f) {
1591: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
1592: PetscInt size;
1594: DMPlexGetSupportSize(dm, f, &size);
1595: DMPlexSetSupportSize(rdm, newp, 4 + size);
1596: }
1597: /* Interior cell vertices have 6 supports */
1598: for (c = cStart; c < cMax; ++c) {
1599: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
1601: DMPlexSetSupportSize(rdm, newp, 6);
1602: }
1603: break;
1604: default:
1605: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
1606: }
1607: return(0);
1608: }
1610: static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
1611: {
1612: const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
1613: PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
1614: PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
1615: PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r;
1616: #if defined(PETSC_USE_DEBUG)
1617: PetscInt p;
1618: #endif
1619: PetscErrorCode ierr;
1622: if (!refiner) return(0);
1623: DMPlexGetDepth(dm, &depth);
1624: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
1625: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
1626: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
1627: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
1628: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
1629: GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);
1630: GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);
1631: switch (refiner) {
1632: case REFINER_SIMPLEX_1D:
1633: /* Max support size of refined mesh is 2 */
1634: PetscMalloc1(2, &supportRef);
1635: /* All cells have 2 vertices */
1636: for (c = cStart; c < cEnd; ++c) {
1637: const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart);
1639: for (r = 0; r < 2; ++r) {
1640: const PetscInt newp = cStartNew + (c - cStart)*2 + r;
1641: const PetscInt *cone;
1642: PetscInt coneNew[2];
1644: DMPlexGetCone(dm, c, &cone);
1645: coneNew[0] = vStartNew + (cone[0] - vStart);
1646: coneNew[1] = vStartNew + (cone[1] - vStart);
1647: coneNew[(r+1)%2] = newv;
1648: DMPlexSetCone(rdm, newp, coneNew);
1649: #if defined(PETSC_USE_DEBUG)
1650: if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp, cStartNew, cEndNew);
1651: for (p = 0; p < 2; ++p) {
1652: 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);
1653: }
1654: #endif
1655: }
1656: }
1657: /* Old vertices have identical supports */
1658: for (v = vStart; v < vEnd; ++v) {
1659: const PetscInt newp = vStartNew + (v - vStart);
1660: const PetscInt *support, *cone;
1661: PetscInt size, s;
1663: DMPlexGetSupportSize(dm, v, &size);
1664: DMPlexGetSupport(dm, v, &support);
1665: for (s = 0; s < size; ++s) {
1666: PetscInt r = 0;
1668: DMPlexGetCone(dm, support[s], &cone);
1669: if (cone[1] == v) r = 1;
1670: supportRef[s] = cStartNew + (support[s] - cStart)*2 + r;
1671: }
1672: DMPlexSetSupport(rdm, newp, supportRef);
1673: #if defined(PETSC_USE_DEBUG)
1674: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
1675: for (p = 0; p < size; ++p) {
1676: 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);
1677: }
1678: #endif
1679: }
1680: /* Cell vertices have support of 2 cells */
1681: for (c = cStart; c < cEnd; ++c) {
1682: const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart);
1684: supportRef[0] = cStartNew + (c - cStart)*2 + 0;
1685: supportRef[1] = cStartNew + (c - cStart)*2 + 1;
1686: DMPlexSetSupport(rdm, newp, supportRef);
1687: #if defined(PETSC_USE_DEBUG)
1688: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
1689: for (p = 0; p < 2; ++p) {
1690: 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);
1691: }
1692: #endif
1693: }
1694: PetscFree(supportRef);
1695: break;
1696: case REFINER_SIMPLEX_2D:
1697: /*
1698: 2
1699: |\
1700: | \
1701: | \
1702: | \
1703: | C \
1704: | \
1705: | \
1706: 2---1---1
1707: |\ D / \
1708: | 2 0 \
1709: |A \ / B \
1710: 0---0-------1
1711: */
1712: /* All cells have 3 faces */
1713: for (c = cStart; c < cEnd; ++c) {
1714: const PetscInt newp = cStartNew + (c - cStart)*4;
1715: const PetscInt *cone, *ornt;
1716: PetscInt coneNew[3], orntNew[3];
1718: DMPlexGetCone(dm, c, &cone);
1719: DMPlexGetConeOrientation(dm, c, &ornt);
1720: /* A triangle */
1721: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1722: orntNew[0] = ornt[0];
1723: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1724: orntNew[1] = -2;
1725: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1726: orntNew[2] = ornt[2];
1727: DMPlexSetCone(rdm, newp+0, coneNew);
1728: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
1729: #if defined(PETSC_USE_DEBUG)
1730: 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);
1731: for (p = 0; p < 3; ++p) {
1732: 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);
1733: }
1734: #endif
1735: /* B triangle */
1736: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1737: orntNew[0] = ornt[0];
1738: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1739: orntNew[1] = ornt[1];
1740: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1741: orntNew[2] = -2;
1742: DMPlexSetCone(rdm, newp+1, coneNew);
1743: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
1744: #if defined(PETSC_USE_DEBUG)
1745: 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);
1746: for (p = 0; p < 3; ++p) {
1747: 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);
1748: }
1749: #endif
1750: /* C triangle */
1751: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1752: orntNew[0] = -2;
1753: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1754: orntNew[1] = ornt[1];
1755: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1756: orntNew[2] = ornt[2];
1757: DMPlexSetCone(rdm, newp+2, coneNew);
1758: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
1759: #if defined(PETSC_USE_DEBUG)
1760: 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);
1761: for (p = 0; p < 3; ++p) {
1762: 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);
1763: }
1764: #endif
1765: /* D triangle */
1766: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1767: orntNew[0] = 0;
1768: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1769: orntNew[1] = 0;
1770: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1771: orntNew[2] = 0;
1772: DMPlexSetCone(rdm, newp+3, coneNew);
1773: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
1774: #if defined(PETSC_USE_DEBUG)
1775: 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);
1776: for (p = 0; p < 3; ++p) {
1777: 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);
1778: }
1779: #endif
1780: }
1781: /* Split faces have 2 vertices and the same cells as the parent */
1782: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
1783: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
1784: for (f = fStart; f < fEnd; ++f) {
1785: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1787: for (r = 0; r < 2; ++r) {
1788: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
1789: const PetscInt *cone, *ornt, *support;
1790: PetscInt coneNew[2], coneSize, c, supportSize, s;
1792: DMPlexGetCone(dm, f, &cone);
1793: coneNew[0] = vStartNew + (cone[0] - vStart);
1794: coneNew[1] = vStartNew + (cone[1] - vStart);
1795: coneNew[(r+1)%2] = newv;
1796: DMPlexSetCone(rdm, newp, coneNew);
1797: #if defined(PETSC_USE_DEBUG)
1798: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1799: for (p = 0; p < 2; ++p) {
1800: 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);
1801: }
1802: #endif
1803: DMPlexGetSupportSize(dm, f, &supportSize);
1804: DMPlexGetSupport(dm, f, &support);
1805: for (s = 0; s < supportSize; ++s) {
1806: DMPlexGetConeSize(dm, support[s], &coneSize);
1807: DMPlexGetCone(dm, support[s], &cone);
1808: DMPlexGetConeOrientation(dm, support[s], &ornt);
1809: for (c = 0; c < coneSize; ++c) {
1810: if (cone[c] == f) break;
1811: }
1812: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
1813: }
1814: DMPlexSetSupport(rdm, newp, supportRef);
1815: #if defined(PETSC_USE_DEBUG)
1816: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1817: for (p = 0; p < supportSize; ++p) {
1818: 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);
1819: }
1820: #endif
1821: }
1822: }
1823: /* Interior faces have 2 vertices and 2 cells */
1824: for (c = cStart; c < cEnd; ++c) {
1825: const PetscInt *cone;
1827: DMPlexGetCone(dm, c, &cone);
1828: for (r = 0; r < 3; ++r) {
1829: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
1830: PetscInt coneNew[2];
1831: PetscInt supportNew[2];
1833: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1834: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
1835: DMPlexSetCone(rdm, newp, coneNew);
1836: #if defined(PETSC_USE_DEBUG)
1837: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1838: for (p = 0; p < 2; ++p) {
1839: 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);
1840: }
1841: #endif
1842: supportNew[0] = (c - cStart)*4 + (r+1)%3;
1843: supportNew[1] = (c - cStart)*4 + 3;
1844: DMPlexSetSupport(rdm, newp, supportNew);
1845: #if defined(PETSC_USE_DEBUG)
1846: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1847: for (p = 0; p < 2; ++p) {
1848: 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);
1849: }
1850: #endif
1851: }
1852: }
1853: /* Old vertices have identical supports */
1854: for (v = vStart; v < vEnd; ++v) {
1855: const PetscInt newp = vStartNew + (v - vStart);
1856: const PetscInt *support, *cone;
1857: PetscInt size, s;
1859: DMPlexGetSupportSize(dm, v, &size);
1860: DMPlexGetSupport(dm, v, &support);
1861: for (s = 0; s < size; ++s) {
1862: PetscInt r = 0;
1864: DMPlexGetCone(dm, support[s], &cone);
1865: if (cone[1] == v) r = 1;
1866: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
1867: }
1868: DMPlexSetSupport(rdm, newp, supportRef);
1869: #if defined(PETSC_USE_DEBUG)
1870: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
1871: for (p = 0; p < size; ++p) {
1872: 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);
1873: }
1874: #endif
1875: }
1876: /* Face vertices have 2 + cells*2 supports */
1877: for (f = fStart; f < fEnd; ++f) {
1878: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
1879: const PetscInt *cone, *support;
1880: PetscInt size, s;
1882: DMPlexGetSupportSize(dm, f, &size);
1883: DMPlexGetSupport(dm, f, &support);
1884: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
1885: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
1886: for (s = 0; s < size; ++s) {
1887: PetscInt r = 0;
1889: DMPlexGetCone(dm, support[s], &cone);
1890: if (cone[1] == f) r = 1;
1891: else if (cone[2] == f) r = 2;
1892: supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
1893: supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
1894: }
1895: DMPlexSetSupport(rdm, newp, supportRef);
1896: #if defined(PETSC_USE_DEBUG)
1897: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
1898: for (p = 0; p < 2+size*2; ++p) {
1899: 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);
1900: }
1901: #endif
1902: }
1903: PetscFree(supportRef);
1904: break;
1905: case REFINER_SIMPLEX_TO_HEX_2D:
1906: /*
1907: 2
1908: |\
1909: | \
1910: | \
1911: | \
1912: | C \
1913: | \
1914: 2 1
1915: |\ / \
1916: | 2 1 \
1917: | \/ \
1918: | | \
1919: |A | B \
1920: | 0 \
1921: | | \
1922: 0---0----------1
1923: */
1924: /* All cells have 4 faces */
1925: for (c = cStart; c < cEnd; ++c) {
1926: const PetscInt newp = cStartNew + (c - cStart)*3;
1927: const PetscInt *cone, *ornt;
1928: PetscInt coneNew[4], orntNew[4];
1930: DMPlexGetCone(dm, c, &cone);
1931: DMPlexGetConeOrientation(dm, c, &ornt);
1932: /* A quad */
1933: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1934: orntNew[0] = ornt[0];
1935: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1936: orntNew[1] = 0;
1937: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1938: orntNew[2] = -2;
1939: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1940: orntNew[3] = ornt[2];
1941: DMPlexSetCone(rdm, newp+0, coneNew);
1942: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
1943: #if defined(PETSC_USE_DEBUG)
1944: 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);
1945: for (p = 0; p < 4; ++p) {
1946: 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);
1947: }
1948: #endif
1949: /* B quad */
1950: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1951: orntNew[0] = ornt[0];
1952: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1953: orntNew[1] = ornt[1];
1954: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1955: orntNew[2] = 0;
1956: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1957: orntNew[3] = -2;
1958: DMPlexSetCone(rdm, newp+1, coneNew);
1959: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
1960: #if defined(PETSC_USE_DEBUG)
1961: 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);
1962: for (p = 0; p < 4; ++p) {
1963: 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);
1964: }
1965: #endif
1966: /* C quad */
1967: coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1968: orntNew[0] = ornt[1];
1969: coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1970: orntNew[1] = ornt[2];
1971: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1972: orntNew[2] = 0;
1973: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1974: orntNew[3] = -2;
1975: DMPlexSetCone(rdm, newp+2, coneNew);
1976: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
1977: #if defined(PETSC_USE_DEBUG)
1978: 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);
1979: for (p = 0; p < 4; ++p) {
1980: 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);
1981: }
1982: #endif
1983: }
1984: /* Split faces have 2 vertices and the same cells as the parent */
1985: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
1986: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
1987: for (f = fStart; f < fEnd; ++f) {
1988: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1990: for (r = 0; r < 2; ++r) {
1991: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
1992: const PetscInt *cone, *ornt, *support;
1993: PetscInt coneNew[2], coneSize, c, supportSize, s;
1995: DMPlexGetCone(dm, f, &cone);
1996: coneNew[0] = vStartNew + (cone[0] - vStart);
1997: coneNew[1] = vStartNew + (cone[1] - vStart);
1998: coneNew[(r+1)%2] = newv;
1999: DMPlexSetCone(rdm, newp, coneNew);
2000: #if defined(PETSC_USE_DEBUG)
2001: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2002: for (p = 0; p < 2; ++p) {
2003: 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);
2004: }
2005: #endif
2006: DMPlexGetSupportSize(dm, f, &supportSize);
2007: DMPlexGetSupport(dm, f, &support);
2008: for (s = 0; s < supportSize; ++s) {
2009: DMPlexGetConeSize(dm, support[s], &coneSize);
2010: DMPlexGetCone(dm, support[s], &cone);
2011: DMPlexGetConeOrientation(dm, support[s], &ornt);
2012: for (c = 0; c < coneSize; ++c) {
2013: if (cone[c] == f) break;
2014: }
2015: supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
2016: }
2017: DMPlexSetSupport(rdm, newp, supportRef);
2018: #if defined(PETSC_USE_DEBUG)
2019: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2020: for (p = 0; p < supportSize; ++p) {
2021: 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);
2022: }
2023: #endif
2024: }
2025: }
2026: /* Interior faces have 2 vertices and 2 cells */
2027: for (c = cStart; c < cEnd; ++c) {
2028: const PetscInt *cone;
2030: DMPlexGetCone(dm, c, &cone);
2031: for (r = 0; r < 3; ++r) {
2032: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
2033: PetscInt coneNew[2];
2034: PetscInt supportNew[2];
2036: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2037: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2038: DMPlexSetCone(rdm, newp, coneNew);
2039: #if defined(PETSC_USE_DEBUG)
2040: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2041: for (p = 0; p < 2; ++p) {
2042: 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);
2043: }
2044: #endif
2045: supportNew[0] = (c - cStart)*3 + r%3;
2046: supportNew[1] = (c - cStart)*3 + (r+1)%3;
2047: DMPlexSetSupport(rdm, newp, supportNew);
2048: #if defined(PETSC_USE_DEBUG)
2049: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2050: for (p = 0; p < 2; ++p) {
2051: 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);
2052: }
2053: #endif
2054: }
2055: }
2056: /* Old vertices have identical supports */
2057: for (v = vStart; v < vEnd; ++v) {
2058: const PetscInt newp = vStartNew + (v - vStart);
2059: const PetscInt *support, *cone;
2060: PetscInt size, s;
2062: DMPlexGetSupportSize(dm, v, &size);
2063: DMPlexGetSupport(dm, v, &support);
2064: for (s = 0; s < size; ++s) {
2065: PetscInt r = 0;
2067: DMPlexGetCone(dm, support[s], &cone);
2068: if (cone[1] == v) r = 1;
2069: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2070: }
2071: DMPlexSetSupport(rdm, newp, supportRef);
2072: #if defined(PETSC_USE_DEBUG)
2073: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2074: for (p = 0; p < size; ++p) {
2075: 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);
2076: }
2077: #endif
2078: }
2079: /* Split-face vertices have cells + 2 supports */
2080: for (f = fStart; f < fEnd; ++f) {
2081: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2082: const PetscInt *cone, *support;
2083: PetscInt size, s;
2085: DMPlexGetSupportSize(dm, f, &size);
2086: DMPlexGetSupport(dm, f, &support);
2087: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2088: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2089: for (s = 0; s < size; ++s) {
2090: PetscInt r = 0;
2092: DMPlexGetCone(dm, support[s], &cone);
2093: if (cone[1] == f) r = 1;
2094: else if (cone[2] == f) r = 2;
2095: supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
2096: }
2097: DMPlexSetSupport(rdm, newp, supportRef);
2098: #if defined(PETSC_USE_DEBUG)
2099: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2100: for (p = 0; p < 2+size; ++p) {
2101: 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);
2102: }
2103: #endif
2104: }
2105: /* Interior vertices have 3 supports */
2106: for (c = cStart; c < cEnd; ++c) {
2107: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
2109: supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2110: supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2111: supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2112: DMPlexSetSupport(rdm, newp, supportRef);
2113: }
2114: PetscFree(supportRef);
2115: break;
2116: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
2117: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2118: cMax = PetscMin(cEnd, cMax);
2119: for (c = cStart; c < cMax; ++c) {
2120: const PetscInt newp = cStartNew + (c - cStart)*3;
2121: const PetscInt *cone, *ornt;
2122: PetscInt coneNew[4], orntNew[4];
2124: DMPlexGetCone(dm, c, &cone);
2125: DMPlexGetConeOrientation(dm, c, &ornt);
2126: /* A quad */
2127: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2128: orntNew[0] = ornt[0];
2129: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2130: orntNew[1] = 0;
2131: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2132: orntNew[2] = -2;
2133: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2134: orntNew[3] = ornt[2];
2135: DMPlexSetCone(rdm, newp+0, coneNew);
2136: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2137: #if defined(PETSC_USE_DEBUG)
2138: 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);
2139: for (p = 0; p < 4; ++p) {
2140: 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);
2141: }
2142: #endif
2143: /* B quad */
2144: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2145: orntNew[0] = ornt[0];
2146: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2147: orntNew[1] = ornt[1];
2148: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2149: orntNew[2] = 0;
2150: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2151: orntNew[3] = -2;
2152: DMPlexSetCone(rdm, newp+1, coneNew);
2153: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2154: #if defined(PETSC_USE_DEBUG)
2155: 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);
2156: for (p = 0; p < 4; ++p) {
2157: 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);
2158: }
2159: #endif
2160: /* C quad */
2161: coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2162: orntNew[0] = ornt[1];
2163: coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2164: orntNew[1] = ornt[2];
2165: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2166: orntNew[2] = 0;
2167: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2168: orntNew[3] = -2;
2169: DMPlexSetCone(rdm, newp+2, coneNew);
2170: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2171: #if defined(PETSC_USE_DEBUG)
2172: 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);
2173: for (p = 0; p < 4; ++p) {
2174: 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);
2175: }
2176: #endif
2177: }
2178: /*
2179: 2---------1---------3
2180: | | |
2181: | D 1 C |
2182: | | |
2183: 2----2----0----3----3
2184: | | |
2185: | A 0 B |
2186: | | |
2187: 0---------0---------1
2188: */
2189: /* Parent cells are input as prisms but children are quads, since the mesh is no longer hybrid */
2190: for (c = cMax; c < cEnd; ++c) {
2191: const PetscInt newp = cStartNew + (cMax - cStart)*3 + (c - cMax)*4;
2192: const PetscInt newpt = (cMax - cStart)*3 + (c - cMax)*4;
2193: const PetscInt *cone, *ornt;
2194: PetscInt coneNew[4], orntNew[4];
2196: DMPlexGetCone(dm, c, &cone);
2197: DMPlexGetConeOrientation(dm, c, &ornt);
2198: /* A quad */
2199: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2200: orntNew[0] = ornt[0];
2201: coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 0;
2202: orntNew[1] = 0;
2203: coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 2;
2204: orntNew[2] = -2;
2205: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2206: orntNew[3] = ornt[2] < 0 ? 0 : -2;
2207: DMPlexSetCone(rdm, newp+0, coneNew);
2208: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2209: #if defined(PETSC_USE_DEBUG)
2210: 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);
2211: for (p = 0; p < 4; ++p) {
2212: 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);
2213: }
2214: #endif
2215: /* B quad */
2216: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2217: orntNew[0] = ornt[0];
2218: coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2219: orntNew[1] = ornt[3];
2220: coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 3;
2221: orntNew[2] = 0;
2222: coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 0;
2223: orntNew[3] = -2;
2224: DMPlexSetCone(rdm, newp+1, coneNew);
2225: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2226: #if defined(PETSC_USE_DEBUG)
2227: 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);
2228: for (p = 0; p < 4; ++p) {
2229: 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);
2230: }
2231: #endif
2232: /* C quad */
2233: coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 3;
2234: orntNew[0] = -2;
2235: coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
2236: orntNew[1] = ornt[3];
2237: coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2238: orntNew[2] = ornt[1] < 0 ? 0 : -2;
2239: coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 1;
2240: orntNew[3] = 0;
2241: DMPlexSetCone(rdm, newp+2, coneNew);
2242: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2243: #if defined(PETSC_USE_DEBUG)
2244: 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);
2245: for (p = 0; p < 4; ++p) {
2246: 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);
2247: }
2248: #endif
2249: /* D quad */
2250: coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 2;
2251: orntNew[0] = 0;
2252: coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 1;
2253: orntNew[1] = -2;
2254: coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2255: orntNew[2] = ornt[1] < 0 ? 0 : -2;
2256: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2257: orntNew[3] = ornt[2] < 0 ? 0 : -2;
2258: DMPlexSetCone(rdm, newp+3, coneNew);
2259: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2260: #if defined(PETSC_USE_DEBUG)
2261: 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);
2262: for (p = 0; p < 4; ++p) {
2263: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew);
2264: }
2265: #endif
2266: }
2267: /* Split faces have 2 vertices and the same cells as the parent */
2268: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2269: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2270: for (f = fStart; f < fEnd; ++f) {
2271: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2273: for (r = 0; r < 2; ++r) {
2274: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2275: const PetscInt *cone, *ornt, *support;
2276: PetscInt coneNew[2], coneSize, c, supportSize, s;
2278: DMPlexGetCone(dm, f, &cone);
2279: coneNew[0] = vStartNew + (cone[0] - vStart);
2280: coneNew[1] = vStartNew + (cone[1] - vStart);
2281: coneNew[(r+1)%2] = newv;
2282: DMPlexSetCone(rdm, newp, coneNew);
2283: #if defined(PETSC_USE_DEBUG)
2284: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2285: for (p = 0; p < 2; ++p) {
2286: 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);
2287: }
2288: #endif
2289: DMPlexGetSupportSize(dm, f, &supportSize);
2290: DMPlexGetSupport(dm, f, &support);
2291: for (s = 0; s < supportSize; ++s) {
2292: const PetscInt p2q[4][2] = { {0, 1},
2293: {3, 2},
2294: {0, 3},
2295: {1, 2} };
2297: DMPlexGetConeSize(dm, support[s], &coneSize);
2298: DMPlexGetCone(dm, support[s], &cone);
2299: DMPlexGetConeOrientation(dm, support[s], &ornt);
2300: for (c = 0; c < coneSize; ++c) {
2301: if (cone[c] == f) break;
2302: }
2303: if (coneSize == 3) supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
2304: 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]);
2305: else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize);
2306: }
2307: DMPlexSetSupport(rdm, newp, supportRef);
2308: #if defined(PETSC_USE_DEBUG)
2309: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2310: for (p = 0; p < supportSize; ++p) {
2311: 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);
2312: }
2313: #endif
2314: }
2315: }
2316: /* Interior faces have 2 vertices and 2 cells */
2317: for (c = cStart; c < cMax; ++c) {
2318: const PetscInt *cone;
2320: DMPlexGetCone(dm, c, &cone);
2321: for (r = 0; r < 3; ++r) {
2322: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
2323: PetscInt coneNew[2];
2324: PetscInt supportNew[2];
2326: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2327: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2328: DMPlexSetCone(rdm, newp, coneNew);
2329: #if defined(PETSC_USE_DEBUG)
2330: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2331: for (p = 0; p < 2; ++p) {
2332: 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);
2333: }
2334: #endif
2335: supportNew[0] = (c - cStart)*3 + r%3;
2336: supportNew[1] = (c - cStart)*3 + (r+1)%3;
2337: DMPlexSetSupport(rdm, newp, supportNew);
2338: #if defined(PETSC_USE_DEBUG)
2339: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2340: for (p = 0; p < 2; ++p) {
2341: 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);
2342: }
2343: #endif
2344: }
2345: }
2346: /* Hybrid interior faces have 2 vertices and 2 cells */
2347: for (c = cMax; c < cEnd; ++c) {
2348: const PetscInt *cone;
2349: PetscInt coneNew[2], supportNew[2];
2351: DMPlexGetCone(dm, c, &cone);
2352: for (r = 0; r < 4; ++r) {
2353: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r;
2355: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2356: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (cMax - cStart) + (c - cMax);
2357: DMPlexSetCone(rdm, newp, coneNew);
2358: #if defined(PETSC_USE_DEBUG)
2359: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2360: for (p = 0; p < 2; ++p) {
2361: 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);
2362: }
2363: #endif
2364: if (r==0) {
2365: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0;
2366: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 1;
2367: } else if (r==1) {
2368: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 2;
2369: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3;
2370: } else if (r==2) {
2371: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0;
2372: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3;
2373: } else {
2374: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 1;
2375: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 2;
2376: }
2377: DMPlexSetSupport(rdm, newp, supportNew);
2378: #if defined(PETSC_USE_DEBUG)
2379: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2380: for (p = 0; p < 2; ++p) {
2381: 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);
2382: }
2383: #endif
2384: }
2385: }
2386: /* Old vertices have identical supports */
2387: for (v = vStart; v < vEnd; ++v) {
2388: const PetscInt newp = vStartNew + (v - vStart);
2389: const PetscInt *support, *cone;
2390: PetscInt size, s;
2392: DMPlexGetSupportSize(dm, v, &size);
2393: DMPlexGetSupport(dm, v, &support);
2394: for (s = 0; s < size; ++s) {
2395: PetscInt r = 0;
2397: DMPlexGetCone(dm, support[s], &cone);
2398: if (cone[1] == v) r = 1;
2399: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2400: }
2401: DMPlexSetSupport(rdm, newp, supportRef);
2402: #if defined(PETSC_USE_DEBUG)
2403: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2404: for (p = 0; p < size; ++p) {
2405: 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);
2406: }
2407: #endif
2408: }
2409: /* Split-face vertices have cells + 2 supports */
2410: for (f = fStart; f < fEnd; ++f) {
2411: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2412: const PetscInt *cone, *support;
2413: PetscInt size, s;
2415: DMPlexGetSupportSize(dm, f, &size);
2416: DMPlexGetSupport(dm, f, &support);
2417: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2418: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2419: for (s = 0; s < size; ++s) {
2420: PetscInt r = 0, coneSize;
2422: DMPlexGetCone(dm, support[s], &cone);
2423: DMPlexGetConeSize(dm, support[s], &coneSize);
2424: if (coneSize == 3) {
2425: if (cone[1] == f) r = 1;
2426: else if (cone[2] == f) r = 2;
2427: supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
2428: } else if (coneSize == 4) {
2429: if (cone[1] == f) r = 1;
2430: else if (cone[2] == f) r = 2;
2431: else if (cone[3] == f) r = 3;
2432: supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (support[s] - cMax)*4 + r;
2433: } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize);
2434: }
2435: DMPlexSetSupport(rdm, newp, supportRef);
2436: #if defined(PETSC_USE_DEBUG)
2437: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2438: for (p = 0; p < 2+size; ++p) {
2439: 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);
2440: }
2441: #endif
2442: }
2443: /* Interior vertices have 3 supports */
2444: for (c = cStart; c < cMax; ++c) {
2445: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
2447: supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2448: supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2449: supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2450: DMPlexSetSupport(rdm, newp, supportRef);
2451: }
2452: /* Hybrid interior vertices have 4 supports */
2453: for (c = cMax; c < cEnd; ++c) {
2454: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
2456: supportRef[0] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 0;
2457: supportRef[1] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 1;
2458: supportRef[2] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 2;
2459: supportRef[3] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 3;
2460: DMPlexSetSupport(rdm, newp, supportRef);
2461: }
2462: PetscFree(supportRef);
2463: break;
2464: case REFINER_HEX_2D:
2465: /*
2466: 3---------2---------2
2467: | | |
2468: | D 2 C |
2469: | | |
2470: 3----3----0----1----1
2471: | | |
2472: | A 0 B |
2473: | | |
2474: 0---------0---------1
2475: */
2476: /* All cells have 4 faces */
2477: for (c = cStart; c < cEnd; ++c) {
2478: const PetscInt newp = (c - cStart)*4;
2479: const PetscInt *cone, *ornt;
2480: PetscInt coneNew[4], orntNew[4];
2482: DMPlexGetCone(dm, c, &cone);
2483: DMPlexGetConeOrientation(dm, c, &ornt);
2484: /* A quad */
2485: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2486: orntNew[0] = ornt[0];
2487: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0;
2488: orntNew[1] = 0;
2489: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3;
2490: orntNew[2] = -2;
2491: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
2492: orntNew[3] = ornt[3];
2493: DMPlexSetCone(rdm, newp+0, coneNew);
2494: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2495: #if defined(PETSC_USE_DEBUG)
2496: 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);
2497: for (p = 0; p < 4; ++p) {
2498: 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);
2499: }
2500: #endif
2501: /* B quad */
2502: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2503: orntNew[0] = ornt[0];
2504: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2505: orntNew[1] = ornt[1];
2506: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1;
2507: orntNew[2] = -2;
2508: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0;
2509: orntNew[3] = -2;
2510: DMPlexSetCone(rdm, newp+1, coneNew);
2511: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2512: #if defined(PETSC_USE_DEBUG)
2513: 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);
2514: for (p = 0; p < 4; ++p) {
2515: 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);
2516: }
2517: #endif
2518: /* C quad */
2519: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1;
2520: orntNew[0] = 0;
2521: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2522: orntNew[1] = ornt[1];
2523: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2524: orntNew[2] = ornt[2];
2525: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2;
2526: orntNew[3] = -2;
2527: DMPlexSetCone(rdm, newp+2, coneNew);
2528: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2529: #if defined(PETSC_USE_DEBUG)
2530: 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);
2531: for (p = 0; p < 4; ++p) {
2532: 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);
2533: }
2534: #endif
2535: /* D quad */
2536: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3;
2537: orntNew[0] = 0;
2538: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2;
2539: orntNew[1] = 0;
2540: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2541: orntNew[2] = ornt[2];
2542: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2543: orntNew[3] = ornt[3];
2544: DMPlexSetCone(rdm, newp+3, coneNew);
2545: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2546: #if defined(PETSC_USE_DEBUG)
2547: 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);
2548: for (p = 0; p < 4; ++p) {
2549: 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);
2550: }
2551: #endif
2552: }
2553: /* Split faces have 2 vertices and the same cells as the parent */
2554: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2555: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2556: for (f = fStart; f < fEnd; ++f) {
2557: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2559: for (r = 0; r < 2; ++r) {
2560: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2561: const PetscInt *cone, *ornt, *support;
2562: PetscInt coneNew[2], coneSize, c, supportSize, s;
2564: DMPlexGetCone(dm, f, &cone);
2565: coneNew[0] = vStartNew + (cone[0] - vStart);
2566: coneNew[1] = vStartNew + (cone[1] - vStart);
2567: coneNew[(r+1)%2] = newv;
2568: DMPlexSetCone(rdm, newp, coneNew);
2569: #if defined(PETSC_USE_DEBUG)
2570: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2571: for (p = 0; p < 2; ++p) {
2572: 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);
2573: }
2574: #endif
2575: DMPlexGetSupportSize(dm, f, &supportSize);
2576: DMPlexGetSupport(dm, f, &support);
2577: for (s = 0; s < supportSize; ++s) {
2578: DMPlexGetConeSize(dm, support[s], &coneSize);
2579: DMPlexGetCone(dm, support[s], &cone);
2580: DMPlexGetConeOrientation(dm, support[s], &ornt);
2581: for (c = 0; c < coneSize; ++c) {
2582: if (cone[c] == f) break;
2583: }
2584: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2585: }
2586: DMPlexSetSupport(rdm, newp, supportRef);
2587: #if defined(PETSC_USE_DEBUG)
2588: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2589: for (p = 0; p < supportSize; ++p) {
2590: 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);
2591: }
2592: #endif
2593: }
2594: }
2595: /* Interior faces have 2 vertices and 2 cells */
2596: for (c = cStart; c < cEnd; ++c) {
2597: const PetscInt *cone;
2598: PetscInt coneNew[2], supportNew[2];
2600: DMPlexGetCone(dm, c, &cone);
2601: for (r = 0; r < 4; ++r) {
2602: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
2604: if (r==1 || r==2) {
2605: coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2606: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2607: } else {
2608: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2609: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2610: }
2611: DMPlexSetCone(rdm, newp, coneNew);
2612: #if defined(PETSC_USE_DEBUG)
2613: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2614: for (p = 0; p < 2; ++p) {
2615: 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);
2616: }
2617: #endif
2618: supportNew[0] = (c - cStart)*4 + r;
2619: supportNew[1] = (c - cStart)*4 + (r+1)%4;
2620: DMPlexSetSupport(rdm, newp, supportNew);
2621: #if defined(PETSC_USE_DEBUG)
2622: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2623: for (p = 0; p < 2; ++p) {
2624: 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);
2625: }
2626: #endif
2627: }
2628: }
2629: /* Old vertices have identical supports */
2630: for (v = vStart; v < vEnd; ++v) {
2631: const PetscInt newp = vStartNew + (v - vStart);
2632: const PetscInt *support, *cone;
2633: PetscInt size, s;
2635: DMPlexGetSupportSize(dm, v, &size);
2636: DMPlexGetSupport(dm, v, &support);
2637: for (s = 0; s < size; ++s) {
2638: PetscInt r = 0;
2640: DMPlexGetCone(dm, support[s], &cone);
2641: if (cone[1] == v) r = 1;
2642: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2643: }
2644: DMPlexSetSupport(rdm, newp, supportRef);
2645: #if defined(PETSC_USE_DEBUG)
2646: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2647: for (p = 0; p < size; ++p) {
2648: 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);
2649: }
2650: #endif
2651: }
2652: /* Face vertices have 2 + cells supports */
2653: for (f = fStart; f < fEnd; ++f) {
2654: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2655: const PetscInt *cone, *support;
2656: PetscInt size, s;
2658: DMPlexGetSupportSize(dm, f, &size);
2659: DMPlexGetSupport(dm, f, &support);
2660: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2661: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2662: for (s = 0; s < size; ++s) {
2663: PetscInt r = 0;
2665: DMPlexGetCone(dm, support[s], &cone);
2666: if (cone[1] == f) r = 1;
2667: else if (cone[2] == f) r = 2;
2668: else if (cone[3] == f) r = 3;
2669: supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
2670: }
2671: DMPlexSetSupport(rdm, newp, supportRef);
2672: #if defined(PETSC_USE_DEBUG)
2673: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2674: for (p = 0; p < 2+size; ++p) {
2675: 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);
2676: }
2677: #endif
2678: }
2679: /* Cell vertices have 4 supports */
2680: for (c = cStart; c < cEnd; ++c) {
2681: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2682: PetscInt supportNew[4];
2684: for (r = 0; r < 4; ++r) {
2685: supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
2686: }
2687: DMPlexSetSupport(rdm, newp, supportNew);
2688: }
2689: PetscFree(supportRef);
2690: break;
2691: case REFINER_HYBRID_SIMPLEX_2D:
2692: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2693: cMax = PetscMin(cEnd, cMax);
2694: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
2695: fMax = PetscMin(fEnd, fMax);
2696: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);
2697: /* Interior cells have 3 faces */
2698: for (c = cStart; c < cMax; ++c) {
2699: const PetscInt newp = cStartNew + (c - cStart)*4;
2700: const PetscInt *cone, *ornt;
2701: PetscInt coneNew[3], orntNew[3];
2703: DMPlexGetCone(dm, c, &cone);
2704: DMPlexGetConeOrientation(dm, c, &ornt);
2705: /* A triangle */
2706: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2707: orntNew[0] = ornt[0];
2708: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2;
2709: orntNew[1] = -2;
2710: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2711: orntNew[2] = ornt[2];
2712: DMPlexSetCone(rdm, newp+0, coneNew);
2713: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2714: #if defined(PETSC_USE_DEBUG)
2715: 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);
2716: for (p = 0; p < 3; ++p) {
2717: 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);
2718: }
2719: #endif
2720: /* B triangle */
2721: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2722: orntNew[0] = ornt[0];
2723: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2724: orntNew[1] = ornt[1];
2725: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0;
2726: orntNew[2] = -2;
2727: DMPlexSetCone(rdm, newp+1, coneNew);
2728: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2729: #if defined(PETSC_USE_DEBUG)
2730: 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);
2731: for (p = 0; p < 3; ++p) {
2732: 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);
2733: }
2734: #endif
2735: /* C triangle */
2736: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1;
2737: orntNew[0] = -2;
2738: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2739: orntNew[1] = ornt[1];
2740: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2741: orntNew[2] = ornt[2];
2742: DMPlexSetCone(rdm, newp+2, coneNew);
2743: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2744: #if defined(PETSC_USE_DEBUG)
2745: 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);
2746: for (p = 0; p < 3; ++p) {
2747: 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);
2748: }
2749: #endif
2750: /* D triangle */
2751: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0;
2752: orntNew[0] = 0;
2753: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1;
2754: orntNew[1] = 0;
2755: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2;
2756: orntNew[2] = 0;
2757: DMPlexSetCone(rdm, newp+3, coneNew);
2758: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2759: #if defined(PETSC_USE_DEBUG)
2760: 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);
2761: for (p = 0; p < 3; ++p) {
2762: 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);
2763: }
2764: #endif
2765: }
2766: /*
2767: 2----3----3
2768: | |
2769: | B |
2770: | |
2771: 0----4--- 1
2772: | |
2773: | A |
2774: | |
2775: 0----2----1
2776: */
2777: /* Hybrid cells have 4 faces */
2778: for (c = cMax; c < cEnd; ++c) {
2779: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
2780: const PetscInt *cone, *ornt;
2781: PetscInt coneNew[4], orntNew[4], r;
2783: DMPlexGetCone(dm, c, &cone);
2784: DMPlexGetConeOrientation(dm, c, &ornt);
2785: r = (ornt[0] < 0 ? 1 : 0);
2786: /* A quad */
2787: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r;
2788: orntNew[0] = ornt[0];
2789: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r;
2790: orntNew[1] = ornt[1];
2791: coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
2792: orntNew[2+r] = 0;
2793: coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
2794: orntNew[3-r] = 0;
2795: DMPlexSetCone(rdm, newp+0, coneNew);
2796: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2797: #if defined(PETSC_USE_DEBUG)
2798: 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);
2799: for (p = 0; p < 4; ++p) {
2800: 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);
2801: }
2802: #endif
2803: /* B quad */
2804: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r;
2805: orntNew[0] = ornt[0];
2806: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r;
2807: orntNew[1] = ornt[1];
2808: coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
2809: orntNew[2+r] = 0;
2810: coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
2811: orntNew[3-r] = 0;
2812: DMPlexSetCone(rdm, newp+1, coneNew);
2813: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2814: #if defined(PETSC_USE_DEBUG)
2815: 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);
2816: for (p = 0; p < 4; ++p) {
2817: 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);
2818: }
2819: #endif
2820: }
2821: /* Interior split faces have 2 vertices and the same cells as the parent */
2822: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2823: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2824: for (f = fStart; f < fMax; ++f) {
2825: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2827: for (r = 0; r < 2; ++r) {
2828: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2829: const PetscInt *cone, *ornt, *support;
2830: PetscInt coneNew[2], coneSize, c, supportSize, s;
2832: DMPlexGetCone(dm, f, &cone);
2833: coneNew[0] = vStartNew + (cone[0] - vStart);
2834: coneNew[1] = vStartNew + (cone[1] - vStart);
2835: coneNew[(r+1)%2] = newv;
2836: DMPlexSetCone(rdm, newp, coneNew);
2837: #if defined(PETSC_USE_DEBUG)
2838: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2839: for (p = 0; p < 2; ++p) {
2840: 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);
2841: }
2842: #endif
2843: DMPlexGetSupportSize(dm, f, &supportSize);
2844: DMPlexGetSupport(dm, f, &support);
2845: for (s = 0; s < supportSize; ++s) {
2846: DMPlexGetConeSize(dm, support[s], &coneSize);
2847: DMPlexGetCone(dm, support[s], &cone);
2848: DMPlexGetConeOrientation(dm, support[s], &ornt);
2849: for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
2850: if (support[s] >= cMax) {
2851: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
2852: } else {
2853: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
2854: }
2855: }
2856: DMPlexSetSupport(rdm, newp, supportRef);
2857: #if defined(PETSC_USE_DEBUG)
2858: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2859: for (p = 0; p < supportSize; ++p) {
2860: 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);
2861: }
2862: #endif
2863: }
2864: }
2865: /* Interior cell faces have 2 vertices and 2 cells */
2866: for (c = cStart; c < cMax; ++c) {
2867: const PetscInt *cone;
2869: DMPlexGetCone(dm, c, &cone);
2870: for (r = 0; r < 3; ++r) {
2871: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
2872: PetscInt coneNew[2];
2873: PetscInt supportNew[2];
2875: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2876: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
2877: DMPlexSetCone(rdm, newp, coneNew);
2878: #if defined(PETSC_USE_DEBUG)
2879: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2880: for (p = 0; p < 2; ++p) {
2881: 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);
2882: }
2883: #endif
2884: supportNew[0] = (c - cStart)*4 + (r+1)%3;
2885: supportNew[1] = (c - cStart)*4 + 3;
2886: DMPlexSetSupport(rdm, newp, supportNew);
2887: #if defined(PETSC_USE_DEBUG)
2888: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2889: for (p = 0; p < 2; ++p) {
2890: 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);
2891: }
2892: #endif
2893: }
2894: }
2895: /* Interior hybrid faces have 2 vertices and the same cells */
2896: for (f = fMax; f < fEnd; ++f) {
2897: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
2898: const PetscInt *cone, *ornt;
2899: const PetscInt *support;
2900: PetscInt coneNew[2];
2901: PetscInt supportNew[2];
2902: PetscInt size, s, r;
2904: DMPlexGetCone(dm, f, &cone);
2905: coneNew[0] = vStartNew + (cone[0] - vStart);
2906: coneNew[1] = vStartNew + (cone[1] - vStart);
2907: DMPlexSetCone(rdm, newp, coneNew);
2908: #if defined(PETSC_USE_DEBUG)
2909: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2910: for (p = 0; p < 2; ++p) {
2911: 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);
2912: }
2913: #endif
2914: DMPlexGetSupportSize(dm, f, &size);
2915: DMPlexGetSupport(dm, f, &support);
2916: for (s = 0; s < size; ++s) {
2917: DMPlexGetCone(dm, support[s], &cone);
2918: DMPlexGetConeOrientation(dm, support[s], &ornt);
2919: for (r = 0; r < 2; ++r) {
2920: if (cone[r+2] == f) break;
2921: }
2922: supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
2923: }
2924: DMPlexSetSupport(rdm, newp, supportNew);
2925: #if defined(PETSC_USE_DEBUG)
2926: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2927: for (p = 0; p < size; ++p) {
2928: 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);
2929: }
2930: #endif
2931: }
2932: /* Cell hybrid faces have 2 vertices and 2 cells */
2933: for (c = cMax; c < cEnd; ++c) {
2934: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
2935: const PetscInt *cone;
2936: PetscInt coneNew[2];
2937: PetscInt supportNew[2];
2939: DMPlexGetCone(dm, c, &cone);
2940: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2941: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2942: DMPlexSetCone(rdm, newp, coneNew);
2943: #if defined(PETSC_USE_DEBUG)
2944: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2945: for (p = 0; p < 2; ++p) {
2946: 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);
2947: }
2948: #endif
2949: supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2950: supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2951: DMPlexSetSupport(rdm, newp, supportNew);
2952: #if defined(PETSC_USE_DEBUG)
2953: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2954: for (p = 0; p < 2; ++p) {
2955: 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);
2956: }
2957: #endif
2958: }
2959: /* Old vertices have identical supports */
2960: for (v = vStart; v < vEnd; ++v) {
2961: const PetscInt newp = vStartNew + (v - vStart);
2962: const PetscInt *support, *cone;
2963: PetscInt size, s;
2965: DMPlexGetSupportSize(dm, v, &size);
2966: DMPlexGetSupport(dm, v, &support);
2967: for (s = 0; s < size; ++s) {
2968: if (support[s] >= fMax) {
2969: supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
2970: } else {
2971: PetscInt r = 0;
2973: DMPlexGetCone(dm, support[s], &cone);
2974: if (cone[1] == v) r = 1;
2975: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2976: }
2977: }
2978: DMPlexSetSupport(rdm, newp, supportRef);
2979: #if defined(PETSC_USE_DEBUG)
2980: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2981: for (p = 0; p < size; ++p) {
2982: 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);
2983: }
2984: #endif
2985: }
2986: /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
2987: for (f = fStart; f < fMax; ++f) {
2988: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2989: const PetscInt *cone, *support;
2990: PetscInt size, newSize = 2, s;
2992: DMPlexGetSupportSize(dm, f, &size);
2993: DMPlexGetSupport(dm, f, &support);
2994: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2995: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2996: for (s = 0; s < size; ++s) {
2997: PetscInt r = 0;
2999: DMPlexGetCone(dm, support[s], &cone);
3000: if (support[s] >= cMax) {
3001: supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
3003: newSize += 1;
3004: } else {
3005: if (cone[1] == f) r = 1;
3006: else if (cone[2] == f) r = 2;
3007: supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
3008: supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
3010: newSize += 2;
3011: }
3012: }
3013: DMPlexSetSupport(rdm, newp, supportRef);
3014: #if defined(PETSC_USE_DEBUG)
3015: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3016: for (p = 0; p < newSize; ++p) {
3017: 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);
3018: }
3019: #endif
3020: }
3021: PetscFree(supportRef);
3022: break;
3023: case REFINER_HYBRID_HEX_2D:
3024: /* Hybrid Hex 2D */
3025: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
3026: cMax = PetscMin(cEnd, cMax);
3027: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
3028: fMax = PetscMin(fEnd, fMax);
3029: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);
3030: /* Interior cells have 4 faces */
3031: for (c = cStart; c < cMax; ++c) {
3032: const PetscInt newp = cStartNew + (c - cStart)*4;
3033: const PetscInt *cone, *ornt;
3034: PetscInt coneNew[4], orntNew[4];
3036: DMPlexGetCone(dm, c, &cone);
3037: DMPlexGetConeOrientation(dm, c, &ornt);
3038: /* A quad */
3039: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
3040: orntNew[0] = ornt[0];
3041: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0;
3042: orntNew[1] = 0;
3043: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3;
3044: orntNew[2] = -2;
3045: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
3046: orntNew[3] = ornt[3];
3047: DMPlexSetCone(rdm, newp+0, coneNew);
3048: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3049: #if defined(PETSC_USE_DEBUG)
3050: 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);
3051: for (p = 0; p < 4; ++p) {
3052: 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);
3053: }
3054: #endif
3055: /* B quad */
3056: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
3057: orntNew[0] = ornt[0];
3058: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
3059: orntNew[1] = ornt[1];
3060: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1;
3061: orntNew[2] = 0;
3062: coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0;
3063: orntNew[3] = -2;
3064: DMPlexSetCone(rdm, newp+1, coneNew);
3065: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3066: #if defined(PETSC_USE_DEBUG)
3067: 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);
3068: for (p = 0; p < 4; ++p) {
3069: 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);
3070: }
3071: #endif
3072: /* C quad */
3073: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1;
3074: orntNew[0] = -2;
3075: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
3076: orntNew[1] = ornt[1];
3077: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
3078: orntNew[2] = ornt[2];
3079: coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2;
3080: orntNew[3] = 0;
3081: DMPlexSetCone(rdm, newp+2, coneNew);
3082: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3083: #if defined(PETSC_USE_DEBUG)
3084: 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);
3085: for (p = 0; p < 4; ++p) {
3086: 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);
3087: }
3088: #endif
3089: /* D quad */
3090: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3;
3091: orntNew[0] = 0;
3092: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2;
3093: orntNew[1] = -2;
3094: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
3095: orntNew[2] = ornt[2];
3096: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
3097: orntNew[3] = ornt[3];
3098: DMPlexSetCone(rdm, newp+3, coneNew);
3099: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3100: #if defined(PETSC_USE_DEBUG)
3101: 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);
3102: for (p = 0; p < 4; ++p) {
3103: 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);
3104: }
3105: #endif
3106: }
3107: /*
3108: 2----3----3
3109: | |
3110: | B |
3111: | |
3112: 0----4--- 1
3113: | |
3114: | A |
3115: | |
3116: 0----2----1
3117: */
3118: /* Hybrid cells have 4 faces */
3119: for (c = cMax; c < cEnd; ++c) {
3120: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
3121: const PetscInt *cone, *ornt;
3122: PetscInt coneNew[4], orntNew[4];
3124: DMPlexGetCone(dm, c, &cone);
3125: DMPlexGetConeOrientation(dm, c, &ornt);
3126: /* A quad */
3127: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
3128: orntNew[0] = ornt[0];
3129: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
3130: orntNew[1] = ornt[1];
3131: coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
3132: orntNew[2] = 0;
3133: coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
3134: orntNew[3] = 0;
3135: DMPlexSetCone(rdm, newp+0, coneNew);
3136: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3137: #if defined(PETSC_USE_DEBUG)
3138: 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);
3139: for (p = 0; p < 4; ++p) {
3140: 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);
3141: }
3142: #endif
3143: /* B quad */
3144: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
3145: orntNew[0] = ornt[0];
3146: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
3147: orntNew[1] = ornt[1];
3148: coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
3149: orntNew[2] = 0;
3150: coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
3151: orntNew[3] = 0;
3152: DMPlexSetCone(rdm, newp+1, coneNew);
3153: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3154: #if defined(PETSC_USE_DEBUG)
3155: 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);
3156: for (p = 0; p < 4; ++p) {
3157: 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);
3158: }
3159: #endif
3160: }
3161: /* Interior split faces have 2 vertices and the same cells as the parent */
3162: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
3163: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
3164: for (f = fStart; f < fMax; ++f) {
3165: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
3167: for (r = 0; r < 2; ++r) {
3168: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
3169: const PetscInt *cone, *ornt, *support;
3170: PetscInt coneNew[2], coneSize, c, supportSize, s;
3172: DMPlexGetCone(dm, f, &cone);
3173: coneNew[0] = vStartNew + (cone[0] - vStart);
3174: coneNew[1] = vStartNew + (cone[1] - vStart);
3175: coneNew[(r+1)%2] = newv;
3176: DMPlexSetCone(rdm, newp, coneNew);
3177: #if defined(PETSC_USE_DEBUG)
3178: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3179: for (p = 0; p < 2; ++p) {
3180: 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);
3181: }
3182: #endif
3183: DMPlexGetSupportSize(dm, f, &supportSize);
3184: DMPlexGetSupport(dm, f, &support);
3185: for (s = 0; s < supportSize; ++s) {
3186: if (support[s] >= cMax) {
3187: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
3188: } else {
3189: DMPlexGetConeSize(dm, support[s], &coneSize);
3190: DMPlexGetCone(dm, support[s], &cone);
3191: DMPlexGetConeOrientation(dm, support[s], &ornt);
3192: for (c = 0; c < coneSize; ++c) {
3193: if (cone[c] == f) break;
3194: }
3195: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
3196: }
3197: }
3198: DMPlexSetSupport(rdm, newp, supportRef);
3199: #if defined(PETSC_USE_DEBUG)
3200: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3201: for (p = 0; p < supportSize; ++p) {
3202: 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);
3203: }
3204: #endif
3205: }
3206: }
3207: /* Interior cell faces have 2 vertices and 2 cells */
3208: for (c = cStart; c < cMax; ++c) {
3209: const PetscInt *cone;
3211: DMPlexGetCone(dm, c, &cone);
3212: for (r = 0; r < 4; ++r) {
3213: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
3214: PetscInt coneNew[2], supportNew[2];
3216: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
3217: coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
3218: DMPlexSetCone(rdm, newp, coneNew);
3219: #if defined(PETSC_USE_DEBUG)
3220: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3221: for (p = 0; p < 2; ++p) {
3222: 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);
3223: }
3224: #endif
3225: supportNew[0] = (c - cStart)*4 + r;
3226: supportNew[1] = (c - cStart)*4 + (r+1)%4;
3227: DMPlexSetSupport(rdm, newp, supportNew);
3228: #if defined(PETSC_USE_DEBUG)
3229: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3230: for (p = 0; p < 2; ++p) {
3231: 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);
3232: }
3233: #endif
3234: }
3235: }
3236: /* Hybrid faces have 2 vertices and the same cells */
3237: for (f = fMax; f < fEnd; ++f) {
3238: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
3239: const PetscInt *cone, *support;
3240: PetscInt coneNew[2], supportNew[2];
3241: PetscInt size, s, r;
3243: DMPlexGetCone(dm, f, &cone);
3244: coneNew[0] = vStartNew + (cone[0] - vStart);
3245: coneNew[1] = vStartNew + (cone[1] - vStart);
3246: DMPlexSetCone(rdm, newp, coneNew);
3247: #if defined(PETSC_USE_DEBUG)
3248: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3249: for (p = 0; p < 2; ++p) {
3250: 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);
3251: }
3252: #endif
3253: DMPlexGetSupportSize(dm, f, &size);
3254: DMPlexGetSupport(dm, f, &support);
3255: for (s = 0; s < size; ++s) {
3256: DMPlexGetCone(dm, support[s], &cone);
3257: for (r = 0; r < 2; ++r) {
3258: if (cone[r+2] == f) break;
3259: }
3260: supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
3261: }
3262: DMPlexSetSupport(rdm, newp, supportNew);
3263: #if defined(PETSC_USE_DEBUG)
3264: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3265: for (p = 0; p < size; ++p) {
3266: 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);
3267: }
3268: #endif
3269: }
3270: /* Cell hybrid faces have 2 vertices and 2 cells */
3271: for (c = cMax; c < cEnd; ++c) {
3272: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
3273: const PetscInt *cone;
3274: PetscInt coneNew[2], supportNew[2];
3276: DMPlexGetCone(dm, c, &cone);
3277: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
3278: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
3279: DMPlexSetCone(rdm, newp, coneNew);
3280: #if defined(PETSC_USE_DEBUG)
3281: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3282: for (p = 0; p < 2; ++p) {
3283: 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);
3284: }
3285: #endif
3286: supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
3287: supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
3288: DMPlexSetSupport(rdm, newp, supportNew);
3289: #if defined(PETSC_USE_DEBUG)
3290: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3291: for (p = 0; p < 2; ++p) {
3292: 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);
3293: }
3294: #endif
3295: }
3296: /* Old vertices have identical supports */
3297: for (v = vStart; v < vEnd; ++v) {
3298: const PetscInt newp = vStartNew + (v - vStart);
3299: const PetscInt *support, *cone;
3300: PetscInt size, s;
3302: DMPlexGetSupportSize(dm, v, &size);
3303: DMPlexGetSupport(dm, v, &support);
3304: for (s = 0; s < size; ++s) {
3305: if (support[s] >= fMax) {
3306: supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
3307: } else {
3308: PetscInt r = 0;
3310: DMPlexGetCone(dm, support[s], &cone);
3311: if (cone[1] == v) r = 1;
3312: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
3313: }
3314: }
3315: DMPlexSetSupport(rdm, newp, supportRef);
3316: #if defined(PETSC_USE_DEBUG)
3317: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3318: for (p = 0; p < size; ++p) {
3319: 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);
3320: }
3321: #endif
3322: }
3323: /* Face vertices have 2 + cells supports */
3324: for (f = fStart; f < fMax; ++f) {
3325: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
3326: const PetscInt *cone, *support;
3327: PetscInt size, s;
3329: DMPlexGetSupportSize(dm, f, &size);
3330: DMPlexGetSupport(dm, f, &support);
3331: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
3332: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
3333: for (s = 0; s < size; ++s) {
3334: PetscInt r = 0;
3336: DMPlexGetCone(dm, support[s], &cone);
3337: if (support[s] >= cMax) {
3338: supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
3339: } else {
3340: if (cone[1] == f) r = 1;
3341: else if (cone[2] == f) r = 2;
3342: else if (cone[3] == f) r = 3;
3343: supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
3344: }
3345: }
3346: DMPlexSetSupport(rdm, newp, supportRef);
3347: #if defined(PETSC_USE_DEBUG)
3348: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3349: for (p = 0; p < 2+size; ++p) {
3350: 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);
3351: }
3352: #endif
3353: }
3354: /* Cell vertices have 4 supports */
3355: for (c = cStart; c < cMax; ++c) {
3356: const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
3357: PetscInt supportNew[4];
3359: for (r = 0; r < 4; ++r) {
3360: supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
3361: }
3362: DMPlexSetSupport(rdm, newp, supportNew);
3363: }
3364: PetscFree(supportRef);
3365: break;
3366: case REFINER_SIMPLEX_3D:
3367: /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
3368: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
3369: for (c = cStart; c < cEnd; ++c) {
3370: const PetscInt newp = cStartNew + (c - cStart)*8;
3371: const PetscInt *cone, *ornt;
3372: PetscInt coneNew[4], orntNew[4];
3374: DMPlexGetCone(dm, c, &cone);
3375: DMPlexGetConeOrientation(dm, c, &ornt);
3376: /* A tetrahedron: {0, a, c, d} */
3377: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
3378: orntNew[0] = ornt[0];
3379: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
3380: orntNew[1] = ornt[1];
3381: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
3382: orntNew[2] = ornt[2];
3383: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0;
3384: orntNew[3] = 0;
3385: DMPlexSetCone(rdm, newp+0, coneNew);
3386: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3387: #if defined(PETSC_USE_DEBUG)
3388: 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);
3389: for (p = 0; p < 4; ++p) {
3390: 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);
3391: }
3392: #endif
3393: /* B tetrahedron: {a, 1, b, e} */
3394: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
3395: orntNew[0] = ornt[0];
3396: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
3397: orntNew[1] = ornt[1];
3398: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1;
3399: orntNew[2] = 0;
3400: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
3401: orntNew[3] = ornt[3];
3402: DMPlexSetCone(rdm, newp+1, coneNew);
3403: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3404: #if defined(PETSC_USE_DEBUG)
3405: 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);
3406: for (p = 0; p < 4; ++p) {
3407: 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);
3408: }
3409: #endif
3410: /* C tetrahedron: {c, b, 2, f} */
3411: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
3412: orntNew[0] = ornt[0];
3413: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2;
3414: orntNew[1] = 0;
3415: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
3416: orntNew[2] = ornt[2];
3417: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
3418: orntNew[3] = ornt[3];
3419: DMPlexSetCone(rdm, newp+2, coneNew);
3420: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3421: #if defined(PETSC_USE_DEBUG)
3422: 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);
3423: for (p = 0; p < 4; ++p) {
3424: 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);
3425: }
3426: #endif
3427: /* D tetrahedron: {d, e, f, 3} */
3428: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3;
3429: orntNew[0] = 0;
3430: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
3431: orntNew[1] = ornt[1];
3432: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
3433: orntNew[2] = ornt[2];
3434: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
3435: orntNew[3] = ornt[3];
3436: DMPlexSetCone(rdm, newp+3, coneNew);
3437: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3438: #if defined(PETSC_USE_DEBUG)
3439: 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);
3440: for (p = 0; p < 4; ++p) {
3441: 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);
3442: }
3443: #endif
3444: /* A' tetrahedron: {c, d, a, f} */
3445: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0;
3446: orntNew[0] = -3;
3447: coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
3448: orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
3449: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3450: orntNew[2] = 0;
3451: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3452: orntNew[3] = 2;
3453: DMPlexSetCone(rdm, newp+4, coneNew);
3454: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
3455: #if defined(PETSC_USE_DEBUG)
3456: 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);
3457: for (p = 0; p < 4; ++p) {
3458: 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);
3459: }
3460: #endif
3461: /* B' tetrahedron: {e, b, a, f} */
3462: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1;
3463: orntNew[0] = -2;
3464: coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
3465: orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1);
3466: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3467: orntNew[2] = 0;
3468: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3469: orntNew[3] = 0;
3470: DMPlexSetCone(rdm, newp+5, coneNew);
3471: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
3472: #if defined(PETSC_USE_DEBUG)
3473: 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);
3474: for (p = 0; p < 4; ++p) {
3475: 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);
3476: }
3477: #endif
3478: /* C' tetrahedron: {f, a, c, b} */
3479: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3480: orntNew[0] = -2;
3481: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3482: orntNew[1] = -2;
3483: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2;
3484: orntNew[2] = -1;
3485: coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3;
3486: orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
3487: DMPlexSetCone(rdm, newp+6, coneNew);
3488: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
3489: #if defined(PETSC_USE_DEBUG)
3490: 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);
3491: for (p = 0; p < 4; ++p) {
3492: 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);
3493: }
3494: #endif
3495: /* D' tetrahedron: {f, a, e, d} */
3496: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3497: orntNew[0] = -2;
3498: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3499: orntNew[1] = -1;
3500: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3;
3501: orntNew[2] = -2;
3502: coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
3503: orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1);
3504: DMPlexSetCone(rdm, newp+7, coneNew);
3505: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
3506: #if defined(PETSC_USE_DEBUG)
3507: 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);
3508: for (p = 0; p < 4; ++p) {
3509: 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);
3510: }
3511: #endif
3512: }
3513: /* Split faces have 3 edges and the same cells as the parent */
3514: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
3515: PetscMalloc1(2 + maxSupportSize*3, &supportRef);
3516: for (f = fStart; f < fEnd; ++f) {
3517: const PetscInt newp = fStartNew + (f - fStart)*4;
3518: const PetscInt *cone, *ornt, *support;
3519: PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s;
3521: DMPlexGetCone(dm, f, &cone);
3522: DMPlexGetConeOrientation(dm, f, &ornt);
3523: /* A triangle */
3524: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
3525: orntNew[0] = ornt[0];
3526: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
3527: orntNew[1] = -2;
3528: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
3529: orntNew[2] = ornt[2];
3530: DMPlexSetCone(rdm, newp+0, coneNew);
3531: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3532: #if defined(PETSC_USE_DEBUG)
3533: 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);
3534: for (p = 0; p < 3; ++p) {
3535: 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);
3536: }
3537: #endif
3538: /* B triangle */
3539: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
3540: orntNew[0] = ornt[0];
3541: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
3542: orntNew[1] = ornt[1];
3543: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
3544: orntNew[2] = -2;
3545: DMPlexSetCone(rdm, newp+1, coneNew);
3546: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3547: #if defined(PETSC_USE_DEBUG)
3548: 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);
3549: for (p = 0; p < 3; ++p) {
3550: 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);
3551: }
3552: #endif
3553: /* C triangle */
3554: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
3555: orntNew[0] = -2;
3556: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
3557: orntNew[1] = ornt[1];
3558: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
3559: orntNew[2] = ornt[2];
3560: DMPlexSetCone(rdm, newp+2, coneNew);
3561: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3562: #if defined(PETSC_USE_DEBUG)
3563: 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);
3564: for (p = 0; p < 3; ++p) {
3565: 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);
3566: }
3567: #endif
3568: /* D triangle */
3569: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
3570: orntNew[0] = 0;
3571: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
3572: orntNew[1] = 0;
3573: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
3574: orntNew[2] = 0;
3575: DMPlexSetCone(rdm, newp+3, coneNew);
3576: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3577: #if defined(PETSC_USE_DEBUG)
3578: 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);
3579: for (p = 0; p < 3; ++p) {
3580: 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);
3581: }
3582: #endif
3583: DMPlexGetSupportSize(dm, f, &supportSize);
3584: DMPlexGetSupport(dm, f, &support);
3585: for (r = 0; r < 4; ++r) {
3586: for (s = 0; s < supportSize; ++s) {
3587: PetscInt subf;
3588: DMPlexGetConeSize(dm, support[s], &coneSize);
3589: DMPlexGetCone(dm, support[s], &cone);
3590: DMPlexGetConeOrientation(dm, support[s], &ornt);
3591: for (c = 0; c < coneSize; ++c) {
3592: if (cone[c] == f) break;
3593: }
3594: subf = GetTriSubfaceInverse_Static(ornt[c], r);
3595: supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
3596: }
3597: DMPlexSetSupport(rdm, newp+r, supportRef);
3598: #if defined(PETSC_USE_DEBUG)
3599: 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);
3600: for (p = 0; p < supportSize; ++p) {
3601: 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);
3602: }
3603: #endif
3604: }
3605: }
3606: /* Interior faces have 3 edges and 2 cells */
3607: for (c = cStart; c < cEnd; ++c) {
3608: PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
3609: const PetscInt *cone, *ornt;
3610: PetscInt coneNew[3], orntNew[3];
3611: PetscInt supportNew[2];
3613: DMPlexGetCone(dm, c, &cone);
3614: DMPlexGetConeOrientation(dm, c, &ornt);
3615: /* Face A: {c, a, d} */
3616: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3617: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3618: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3619: orntNew[1] = ornt[1] < 0 ? -2 : 0;
3620: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
3621: orntNew[2] = ornt[2] < 0 ? -2 : 0;
3622: DMPlexSetCone(rdm, newp, coneNew);
3623: DMPlexSetConeOrientation(rdm, newp, orntNew);
3624: #if defined(PETSC_USE_DEBUG)
3625: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3626: for (p = 0; p < 3; ++p) {
3627: 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);
3628: }
3629: #endif
3630: supportNew[0] = (c - cStart)*8 + 0;
3631: supportNew[1] = (c - cStart)*8 + 0+4;
3632: DMPlexSetSupport(rdm, newp, supportNew);
3633: #if defined(PETSC_USE_DEBUG)
3634: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3635: for (p = 0; p < 2; ++p) {
3636: 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);
3637: }
3638: #endif
3639: ++newp;
3640: /* Face B: {a, b, e} */
3641: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3642: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3643: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
3644: orntNew[1] = ornt[3] < 0 ? -2 : 0;
3645: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3646: orntNew[2] = ornt[1] < 0 ? -2 : 0;
3647: DMPlexSetCone(rdm, newp, coneNew);
3648: DMPlexSetConeOrientation(rdm, newp, orntNew);
3649: #if defined(PETSC_USE_DEBUG)
3650: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3651: for (p = 0; p < 3; ++p) {
3652: 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);
3653: }
3654: #endif
3655: supportNew[0] = (c - cStart)*8 + 1;
3656: supportNew[1] = (c - cStart)*8 + 1+4;
3657: DMPlexSetSupport(rdm, newp, supportNew);
3658: #if defined(PETSC_USE_DEBUG)
3659: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3660: for (p = 0; p < 2; ++p) {
3661: 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);
3662: }
3663: #endif
3664: ++newp;
3665: /* Face C: {c, f, b} */
3666: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
3667: orntNew[0] = ornt[2] < 0 ? -2 : 0;
3668: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3669: orntNew[1] = ornt[3] < 0 ? -2 : 0;
3670: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
3671: orntNew[2] = ornt[0] < 0 ? -2 : 0;
3672: DMPlexSetCone(rdm, newp, coneNew);
3673: DMPlexSetConeOrientation(rdm, newp, orntNew);
3674: #if defined(PETSC_USE_DEBUG)
3675: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3676: for (p = 0; p < 3; ++p) {
3677: 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);
3678: }
3679: #endif
3680: supportNew[0] = (c - cStart)*8 + 2;
3681: supportNew[1] = (c - cStart)*8 + 2+4;
3682: DMPlexSetSupport(rdm, newp, supportNew);
3683: #if defined(PETSC_USE_DEBUG)
3684: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3685: for (p = 0; p < 2; ++p) {
3686: 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);
3687: }
3688: #endif
3689: ++newp;
3690: /* Face D: {d, e, f} */
3691: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
3692: orntNew[0] = ornt[1] < 0 ? -2 : 0;
3693: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3694: orntNew[1] = ornt[3] < 0 ? -2 : 0;
3695: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3696: orntNew[2] = ornt[2] < 0 ? -2 : 0;
3697: DMPlexSetCone(rdm, newp, coneNew);
3698: DMPlexSetConeOrientation(rdm, newp, orntNew);
3699: #if defined(PETSC_USE_DEBUG)
3700: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3701: for (p = 0; p < 3; ++p) {
3702: 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);
3703: }
3704: #endif
3705: supportNew[0] = (c - cStart)*8 + 3;
3706: supportNew[1] = (c - cStart)*8 + 3+4;
3707: DMPlexSetSupport(rdm, newp, supportNew);
3708: #if defined(PETSC_USE_DEBUG)
3709: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3710: for (p = 0; p < 2; ++p) {
3711: 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);
3712: }
3713: #endif
3714: ++newp;
3715: /* Face E: {d, f, a} */
3716: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3717: orntNew[0] = ornt[2] < 0 ? 0 : -2;
3718: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3719: orntNew[1] = -2;
3720: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3721: orntNew[2] = ornt[1] < 0 ? -2 : 0;
3722: DMPlexSetCone(rdm, newp, coneNew);
3723: DMPlexSetConeOrientation(rdm, newp, orntNew);
3724: #if defined(PETSC_USE_DEBUG)
3725: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3726: for (p = 0; p < 3; ++p) {
3727: 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);
3728: }
3729: #endif
3730: supportNew[0] = (c - cStart)*8 + 0+4;
3731: supportNew[1] = (c - cStart)*8 + 3+4;
3732: DMPlexSetSupport(rdm, newp, supportNew);
3733: #if defined(PETSC_USE_DEBUG)
3734: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3735: for (p = 0; p < 2; ++p) {
3736: 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);
3737: }
3738: #endif
3739: ++newp;
3740: /* Face F: {c, a, f} */
3741: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3742: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3743: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3744: orntNew[1] = 0;
3745: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
3746: orntNew[2] = ornt[2] < 0 ? 0 : -2;
3747: DMPlexSetCone(rdm, newp, coneNew);
3748: DMPlexSetConeOrientation(rdm, newp, orntNew);
3749: #if defined(PETSC_USE_DEBUG)
3750: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3751: for (p = 0; p < 3; ++p) {
3752: 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);
3753: }
3754: #endif
3755: supportNew[0] = (c - cStart)*8 + 0+4;
3756: supportNew[1] = (c - cStart)*8 + 2+4;
3757: DMPlexSetSupport(rdm, newp, supportNew);
3758: #if defined(PETSC_USE_DEBUG)
3759: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3760: for (p = 0; p < 2; ++p) {
3761: 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);
3762: }
3763: #endif
3764: ++newp;
3765: /* Face G: {e, a, f} */
3766: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3767: orntNew[0] = ornt[1] < 0 ? -2 : 0;
3768: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3769: orntNew[1] = 0;
3770: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3771: orntNew[2] = ornt[3] < 0 ? 0 : -2;
3772: DMPlexSetCone(rdm, newp, coneNew);
3773: DMPlexSetConeOrientation(rdm, newp, orntNew);
3774: #if defined(PETSC_USE_DEBUG)
3775: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3776: for (p = 0; p < 3; ++p) {
3777: 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);
3778: }
3779: #endif
3780: supportNew[0] = (c - cStart)*8 + 1+4;
3781: supportNew[1] = (c - cStart)*8 + 3+4;
3782: DMPlexSetSupport(rdm, newp, supportNew);
3783: #if defined(PETSC_USE_DEBUG)
3784: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3785: for (p = 0; p < 2; ++p) {
3786: 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);
3787: }
3788: #endif
3789: ++newp;
3790: /* Face H: {a, b, f} */
3791: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3792: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3793: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3794: orntNew[1] = ornt[3] < 0 ? 0 : -2;
3795: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3796: orntNew[2] = -2;
3797: DMPlexSetCone(rdm, newp, coneNew);
3798: DMPlexSetConeOrientation(rdm, newp, orntNew);
3799: #if defined(PETSC_USE_DEBUG)
3800: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3801: for (p = 0; p < 3; ++p) {
3802: 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);
3803: }
3804: #endif
3805: supportNew[0] = (c - cStart)*8 + 1+4;
3806: supportNew[1] = (c - cStart)*8 + 2+4;
3807: DMPlexSetSupport(rdm, newp, supportNew);
3808: #if defined(PETSC_USE_DEBUG)
3809: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3810: for (p = 0; p < 2; ++p) {
3811: 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);
3812: }
3813: #endif
3814: ++newp;
3815: }
3816: /* Split Edges have 2 vertices and the same faces as the parent */
3817: for (e = eStart; e < eEnd; ++e) {
3818: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
3820: for (r = 0; r < 2; ++r) {
3821: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
3822: const PetscInt *cone, *ornt, *support;
3823: PetscInt coneNew[2], coneSize, c, supportSize, s;
3825: DMPlexGetCone(dm, e, &cone);
3826: coneNew[0] = vStartNew + (cone[0] - vStart);
3827: coneNew[1] = vStartNew + (cone[1] - vStart);
3828: coneNew[(r+1)%2] = newv;
3829: DMPlexSetCone(rdm, newp, coneNew);
3830: #if defined(PETSC_USE_DEBUG)
3831: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
3832: for (p = 0; p < 2; ++p) {
3833: 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);
3834: }
3835: #endif
3836: DMPlexGetSupportSize(dm, e, &supportSize);
3837: DMPlexGetSupport(dm, e, &support);
3838: for (s = 0; s < supportSize; ++s) {
3839: DMPlexGetConeSize(dm, support[s], &coneSize);
3840: DMPlexGetCone(dm, support[s], &cone);
3841: DMPlexGetConeOrientation(dm, support[s], &ornt);
3842: for (c = 0; c < coneSize; ++c) {
3843: if (cone[c] == e) break;
3844: }
3845: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
3846: }
3847: DMPlexSetSupport(rdm, newp, supportRef);
3848: #if defined(PETSC_USE_DEBUG)
3849: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
3850: for (p = 0; p < supportSize; ++p) {
3851: 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);
3852: }
3853: #endif
3854: }
3855: }
3856: /* Face edges have 2 vertices and 2+cells*(1/2) faces */
3857: for (f = fStart; f < fEnd; ++f) {
3858: const PetscInt *cone, *ornt, *support;
3859: PetscInt coneSize, supportSize, s;
3861: DMPlexGetSupportSize(dm, f, &supportSize);
3862: DMPlexGetSupport(dm, f, &support);
3863: for (r = 0; r < 3; ++r) {
3864: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
3865: PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
3866: PetscInt fint[24] = { 1, 7, -1, -1, 0, 5,
3867: -1, -1, 1, 6, 0, 4,
3868: 2, 5, 3, 4, -1, -1,
3869: -1, -1, 3, 6, 2, 7};
3871: DMPlexGetCone(dm, f, &cone);
3872: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
3873: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
3874: DMPlexSetCone(rdm, newp, coneNew);
3875: #if defined(PETSC_USE_DEBUG)
3876: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
3877: for (p = 0; p < 2; ++p) {
3878: 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);
3879: }
3880: #endif
3881: supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
3882: supportRef[1] = fStartNew + (f - fStart)*4 + 3;
3883: for (s = 0; s < supportSize; ++s) {
3884: DMPlexGetConeSize(dm, support[s], &coneSize);
3885: DMPlexGetCone(dm, support[s], &cone);
3886: DMPlexGetConeOrientation(dm, support[s], &ornt);
3887: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
3888: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
3889: er = GetTriMidEdgeInverse_Static(ornt[c], r);
3890: if (er == eint[c]) {
3891: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
3892: } else {
3893: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
3894: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
3895: }
3896: }
3897: DMPlexSetSupport(rdm, newp, supportRef);
3898: #if defined(PETSC_USE_DEBUG)
3899: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
3900: for (p = 0; p < intFaces; ++p) {
3901: 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);
3902: }
3903: #endif
3904: }
3905: }
3906: /* Interior edges have 2 vertices and 4 faces */
3907: for (c = cStart; c < cEnd; ++c) {
3908: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3909: const PetscInt *cone, *ornt, *fcone;
3910: PetscInt coneNew[2], supportNew[4], find;
3912: DMPlexGetCone(dm, c, &cone);
3913: DMPlexGetConeOrientation(dm, c, &ornt);
3914: DMPlexGetCone(dm, cone[0], &fcone);
3915: find = GetTriEdge_Static(ornt[0], 0);
3916: coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3917: DMPlexGetCone(dm, cone[2], &fcone);
3918: find = GetTriEdge_Static(ornt[2], 1);
3919: coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3920: DMPlexSetCone(rdm, newp, coneNew);
3921: #if defined(PETSC_USE_DEBUG)
3922: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
3923: for (p = 0; p < 2; ++p) {
3924: 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);
3925: }
3926: #endif
3927: supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3928: supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3929: supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3930: supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3931: DMPlexSetSupport(rdm, newp, supportNew);
3932: #if defined(PETSC_USE_DEBUG)
3933: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
3934: for (p = 0; p < 4; ++p) {
3935: 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);
3936: }
3937: #endif
3938: }
3939: /* Old vertices have identical supports */
3940: for (v = vStart; v < vEnd; ++v) {
3941: const PetscInt newp = vStartNew + (v - vStart);
3942: const PetscInt *support, *cone;
3943: PetscInt size, s;
3945: DMPlexGetSupportSize(dm, v, &size);
3946: DMPlexGetSupport(dm, v, &support);
3947: for (s = 0; s < size; ++s) {
3948: PetscInt r = 0;
3950: DMPlexGetCone(dm, support[s], &cone);
3951: if (cone[1] == v) r = 1;
3952: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
3953: }
3954: DMPlexSetSupport(rdm, newp, supportRef);
3955: #if defined(PETSC_USE_DEBUG)
3956: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3957: for (p = 0; p < size; ++p) {
3958: 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);
3959: }
3960: #endif
3961: }
3962: /* Edge vertices have 2 + face*2 + 0/1 supports */
3963: for (e = eStart; e < eEnd; ++e) {
3964: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
3965: const PetscInt *cone, *support;
3966: PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s;
3968: DMPlexGetSupportSize(dm, e, &size);
3969: DMPlexGetSupport(dm, e, &support);
3970: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
3971: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
3972: for (s = 0; s < size; ++s) {
3973: PetscInt r = 0;
3975: DMPlexGetConeSize(dm, support[s], &coneSize);
3976: DMPlexGetCone(dm, support[s], &cone);
3977: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
3978: supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
3979: supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
3980: }
3981: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
3982: for (s = 0; s < starSize*2; s += 2) {
3983: const PetscInt *cone, *ornt;
3984: PetscInt e01, e23;
3986: if ((star[s] >= cStart) && (star[s] < cEnd)) {
3987: /* Check edge 0-1 */
3988: DMPlexGetCone(dm, star[s], &cone);
3989: DMPlexGetConeOrientation(dm, star[s], &ornt);
3990: DMPlexGetCone(dm, cone[0], &cone);
3991: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
3992: /* Check edge 2-3 */
3993: DMPlexGetCone(dm, star[s], &cone);
3994: DMPlexGetConeOrientation(dm, star[s], &ornt);
3995: DMPlexGetCone(dm, cone[2], &cone);
3996: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
3997: if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
3998: }
3999: }
4000: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
4001: DMPlexSetSupport(rdm, newp, supportRef);
4002: #if defined(PETSC_USE_DEBUG)
4003: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
4004: for (p = 0; p < 2+size*2+cellSize; ++p) {
4005: 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);
4006: }
4007: #endif
4008: }
4009: PetscFree(supportRef);
4010: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
4011: break;
4012: case REFINER_HYBRID_SIMPLEX_3D:
4013: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);
4014: /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
4015: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
4016: for (c = cStart; c < cMax; ++c) {
4017: const PetscInt newp = cStartNew + (c - cStart)*8;
4018: const PetscInt *cone, *ornt;
4019: PetscInt coneNew[4], orntNew[4];
4021: DMPlexGetCone(dm, c, &cone);
4022: DMPlexGetConeOrientation(dm, c, &ornt);
4023: /* A tetrahedron: {0, a, c, d} */
4024: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
4025: orntNew[0] = ornt[0];
4026: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
4027: orntNew[1] = ornt[1];
4028: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
4029: orntNew[2] = ornt[2];
4030: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0;
4031: orntNew[3] = 0;
4032: DMPlexSetCone(rdm, newp+0, coneNew);
4033: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
4034: #if defined(PETSC_USE_DEBUG)
4035: 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);
4036: for (p = 0; p < 4; ++p) {
4037: 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);
4038: }
4039: #endif
4040: /* B tetrahedron: {a, 1, b, e} */
4041: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
4042: orntNew[0] = ornt[0];
4043: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
4044: orntNew[1] = ornt[1];
4045: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1;
4046: orntNew[2] = 0;
4047: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
4048: orntNew[3] = ornt[3];
4049: DMPlexSetCone(rdm, newp+1, coneNew);
4050: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
4051: #if defined(PETSC_USE_DEBUG)
4052: 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);
4053: for (p = 0; p < 4; ++p) {
4054: 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);
4055: }
4056: #endif
4057: /* C tetrahedron: {c, b, 2, f} */
4058: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
4059: orntNew[0] = ornt[0];
4060: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2;
4061: orntNew[1] = 0;
4062: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
4063: orntNew[2] = ornt[2];
4064: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
4065: orntNew[3] = ornt[3];
4066: DMPlexSetCone(rdm, newp+2, coneNew);
4067: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
4068: #if defined(PETSC_USE_DEBUG)
4069: 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);
4070: for (p = 0; p < 4; ++p) {
4071: 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);
4072: }
4073: #endif
4074: /* D tetrahedron: {d, e, f, 3} */
4075: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3;
4076: orntNew[0] = 0;
4077: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
4078: orntNew[1] = ornt[1];
4079: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
4080: orntNew[2] = ornt[2];
4081: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
4082: orntNew[3] = ornt[3];
4083: DMPlexSetCone(rdm, newp+3, coneNew);
4084: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
4085: #if defined(PETSC_USE_DEBUG)
4086: 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);
4087: for (p = 0; p < 4; ++p) {
4088: 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);
4089: }
4090: #endif
4091: /* A' tetrahedron: {d, a, c, f} */
4092: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0;
4093: orntNew[0] = -3;
4094: coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
4095: orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
4096: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
4097: orntNew[2] = 0;
4098: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
4099: orntNew[3] = 2;
4100: DMPlexSetCone(rdm, newp+4, coneNew);
4101: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
4102: #if defined(PETSC_USE_DEBUG)
4103: 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);
4104: for (p = 0; p < 4; ++p) {
4105: 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);
4106: }
4107: #endif
4108: /* B' tetrahedron: {e, b, a, f} */
4109: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1;
4110: orntNew[0] = -3;
4111: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
4112: orntNew[1] = 1;
4113: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
4114: orntNew[2] = 0;
4115: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
4116: orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0);
4117: DMPlexSetCone(rdm, newp+5, coneNew);
4118: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
4119: #if defined(PETSC_USE_DEBUG)
4120: 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);
4121: for (p = 0; p < 4; ++p) {
4122: 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);
4123: }
4124: #endif
4125: /* C' tetrahedron: {b, f, c, a} */
4126: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2;
4127: orntNew[0] = -3;
4128: coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
4129: orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
4130: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
4131: orntNew[2] = -3;
4132: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
4133: orntNew[3] = -2;
4134: DMPlexSetCone(rdm, newp+6, coneNew);
4135: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
4136: #if defined(PETSC_USE_DEBUG)
4137: 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);
4138: for (p = 0; p < 4; ++p) {
4139: 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);
4140: }
4141: #endif
4142: /* D' tetrahedron: {f, e, d, a} */
4143: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3;
4144: orntNew[0] = -3;
4145: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
4146: orntNew[1] = -3;
4147: coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
4148: orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0);
4149: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
4150: orntNew[3] = -3;
4151: DMPlexSetCone(rdm, newp+7, coneNew);
4152: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
4153: #if defined(PETSC_USE_DEBUG)
4154: 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);
4155: for (p = 0; p < 4; ++p) {
4156: 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);
4157: }
4158: #endif
4159: }
4160: /* Hybrid cells have 5 faces */
4161: for (c = cMax; c < cEnd; ++c) {
4162: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
4163: const PetscInt *cone, *ornt, *fornt;
4164: PetscInt coneNew[5], orntNew[5], o, of, i;
4166: DMPlexGetCone(dm, c, &cone);
4167: DMPlexGetConeOrientation(dm, c, &ornt);
4168: DMPlexGetConeOrientation(dm, cone[0], &fornt);
4169: o = ornt[0] < 0 ? -1 : 1;
4170: for (r = 0; r < 3; ++r) {
4171: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
4172: orntNew[0] = ornt[0];
4173: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
4174: orntNew[1] = ornt[1];
4175: of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1;
4176: i = GetTriEdgeInverse_Static(ornt[0], r) + 2;
4177: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0);
4178: orntNew[i] = 0;
4179: i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
4180: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
4181: orntNew[i] = 0;
4182: of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
4183: i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
4184: 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);
4185: orntNew[i] = 0;
4186: DMPlexSetCone(rdm, newp+r, coneNew);
4187: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
4188: #if defined(PETSC_USE_DEBUG)
4189: 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);
4190: for (p = 0; p < 2; ++p) {
4191: 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);
4192: }
4193: for (p = 2; p < 5; ++p) {
4194: 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);
4195: }
4196: #endif
4197: }
4198: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
4199: orntNew[0] = 0;
4200: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
4201: orntNew[1] = 0;
4202: coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
4203: orntNew[2] = 0;
4204: coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
4205: orntNew[3] = 0;
4206: coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
4207: orntNew[4] = 0;
4208: DMPlexSetCone(rdm, newp+3, coneNew);
4209: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
4210: #if defined(PETSC_USE_DEBUG)
4211: 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);
4212: for (p = 0; p < 2; ++p) {
4213: 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);
4214: }
4215: for (p = 2; p < 5; ++p) {
4216: 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);
4217: }
4218: #endif
4219: }
4220: /* Split faces have 3 edges and the same cells as the parent */
4221: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
4222: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
4223: for (f = fStart; f < fMax; ++f) {
4224: const PetscInt newp = fStartNew + (f - fStart)*4;
4225: const PetscInt *cone, *ornt, *support;
4226: PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s;
4228: DMPlexGetCone(dm, f, &cone);
4229: DMPlexGetConeOrientation(dm, f, &ornt);
4230: /* A triangle */
4231: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
4232: orntNew[0] = ornt[0];
4233: coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
4234: orntNew[1] = -2;
4235: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
4236: orntNew[2] = ornt[2];
4237: DMPlexSetCone(rdm, newp+0, coneNew);
4238: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
4239: #if defined(PETSC_USE_DEBUG)
4240: 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);
4241: for (p = 0; p < 3; ++p) {
4242: 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);
4243: }
4244: #endif
4245: /* B triangle */
4246: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
4247: orntNew[0] = ornt[0];
4248: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
4249: orntNew[1] = ornt[1];
4250: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
4251: orntNew[2] = -2;
4252: DMPlexSetCone(rdm, newp+1, coneNew);
4253: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
4254: #if defined(PETSC_USE_DEBUG)
4255: 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);
4256: for (p = 0; p < 3; ++p) {
4257: 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);
4258: }
4259: #endif
4260: /* C triangle */
4261: coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
4262: orntNew[0] = -2;
4263: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
4264: orntNew[1] = ornt[1];
4265: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
4266: orntNew[2] = ornt[2];
4267: DMPlexSetCone(rdm, newp+2, coneNew);
4268: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
4269: #if defined(PETSC_USE_DEBUG)
4270: 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);
4271: for (p = 0; p < 3; ++p) {
4272: 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);
4273: }
4274: #endif
4275: /* D triangle */
4276: coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
4277: orntNew[0] = 0;
4278: coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
4279: orntNew[1] = 0;
4280: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
4281: orntNew[2] = 0;
4282: DMPlexSetCone(rdm, newp+3, coneNew);
4283: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
4284: #if defined(PETSC_USE_DEBUG)
4285: 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);
4286: for (p = 0; p < 3; ++p) {
4287: 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);
4288: }
4289: #endif
4290: DMPlexGetSupportSize(dm, f, &supportSize);
4291: DMPlexGetSupport(dm, f, &support);
4292: for (r = 0; r < 4; ++r) {
4293: for (s = 0; s < supportSize; ++s) {
4294: PetscInt subf;
4295: DMPlexGetConeSize(dm, support[s], &coneSize);
4296: DMPlexGetCone(dm, support[s], &cone);
4297: DMPlexGetConeOrientation(dm, support[s], &ornt);
4298: for (c = 0; c < coneSize; ++c) {
4299: if (cone[c] == f) break;
4300: }
4301: subf = GetTriSubfaceInverse_Static(ornt[c], r);
4302: if (support[s] < cMax) {
4303: supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
4304: } else {
4305: supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
4306: }
4307: }
4308: DMPlexSetSupport(rdm, newp+r, supportRef);
4309: #if defined(PETSC_USE_DEBUG)
4310: 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);
4311: for (p = 0; p < supportSize; ++p) {
4312: 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);
4313: }
4314: #endif
4315: }
4316: }
4317: /* Interior cell faces have 3 edges and 2 cells */
4318: for (c = cStart; c < cMax; ++c) {
4319: PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
4320: const PetscInt *cone, *ornt;
4321: PetscInt coneNew[3], orntNew[3];
4322: PetscInt supportNew[2];
4324: DMPlexGetCone(dm, c, &cone);
4325: DMPlexGetConeOrientation(dm, c, &ornt);
4326: /* Face A: {c, a, d} */
4327: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
4328: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4329: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
4330: orntNew[1] = ornt[1] < 0 ? -2 : 0;
4331: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
4332: orntNew[2] = ornt[2] < 0 ? -2 : 0;
4333: DMPlexSetCone(rdm, newp, coneNew);
4334: DMPlexSetConeOrientation(rdm, newp, orntNew);
4335: #if defined(PETSC_USE_DEBUG)
4336: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4337: for (p = 0; p < 3; ++p) {
4338: 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);
4339: }
4340: #endif
4341: supportNew[0] = (c - cStart)*8 + 0;
4342: supportNew[1] = (c - cStart)*8 + 0+4;
4343: DMPlexSetSupport(rdm, newp, supportNew);
4344: #if defined(PETSC_USE_DEBUG)
4345: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4346: for (p = 0; p < 2; ++p) {
4347: 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);
4348: }
4349: #endif
4350: ++newp;
4351: /* Face B: {a, b, e} */
4352: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
4353: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4354: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
4355: orntNew[1] = ornt[3] < 0 ? -2 : 0;
4356: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
4357: orntNew[2] = ornt[1] < 0 ? -2 : 0;
4358: DMPlexSetCone(rdm, newp, coneNew);
4359: DMPlexSetConeOrientation(rdm, newp, orntNew);
4360: #if defined(PETSC_USE_DEBUG)
4361: 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);
4362: for (p = 0; p < 3; ++p) {
4363: 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);
4364: }
4365: #endif
4366: supportNew[0] = (c - cStart)*8 + 1;
4367: supportNew[1] = (c - cStart)*8 + 1+4;
4368: DMPlexSetSupport(rdm, newp, supportNew);
4369: #if defined(PETSC_USE_DEBUG)
4370: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4371: for (p = 0; p < 2; ++p) {
4372: 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);
4373: }
4374: #endif
4375: ++newp;
4376: /* Face C: {c, f, b} */
4377: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
4378: orntNew[0] = ornt[2] < 0 ? -2 : 0;
4379: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
4380: orntNew[1] = ornt[3] < 0 ? -2 : 0;
4381: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
4382: orntNew[2] = ornt[0] < 0 ? -2 : 0;
4383: DMPlexSetCone(rdm, newp, coneNew);
4384: DMPlexSetConeOrientation(rdm, newp, orntNew);
4385: #if defined(PETSC_USE_DEBUG)
4386: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4387: for (p = 0; p < 3; ++p) {
4388: 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);
4389: }
4390: #endif
4391: supportNew[0] = (c - cStart)*8 + 2;
4392: supportNew[1] = (c - cStart)*8 + 2+4;
4393: DMPlexSetSupport(rdm, newp, supportNew);
4394: #if defined(PETSC_USE_DEBUG)
4395: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4396: for (p = 0; p < 2; ++p) {
4397: 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);
4398: }
4399: #endif
4400: ++newp;
4401: /* Face D: {d, e, f} */
4402: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
4403: orntNew[0] = ornt[1] < 0 ? -2 : 0;
4404: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
4405: orntNew[1] = ornt[3] < 0 ? -2 : 0;
4406: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
4407: orntNew[2] = ornt[2] < 0 ? -2 : 0;
4408: DMPlexSetCone(rdm, newp, coneNew);
4409: DMPlexSetConeOrientation(rdm, newp, orntNew);
4410: #if defined(PETSC_USE_DEBUG)
4411: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4412: for (p = 0; p < 3; ++p) {
4413: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew);
4414: }
4415: #endif
4416: supportNew[0] = (c - cStart)*8 + 3;
4417: supportNew[1] = (c - cStart)*8 + 3+4;
4418: DMPlexSetSupport(rdm, newp, supportNew);
4419: #if defined(PETSC_USE_DEBUG)
4420: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4421: for (p = 0; p < 2; ++p) {
4422: 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);
4423: }
4424: #endif
4425: ++newp;
4426: /* Face E: {d, f, a} */
4427: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
4428: orntNew[0] = ornt[2] < 0 ? 0 : -2;
4429: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4430: orntNew[1] = -2;
4431: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
4432: orntNew[2] = ornt[1] < 0 ? -2 : 0;
4433: DMPlexSetCone(rdm, newp, coneNew);
4434: DMPlexSetConeOrientation(rdm, newp, orntNew);
4435: #if defined(PETSC_USE_DEBUG)
4436: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4437: for (p = 0; p < 3; ++p) {
4438: 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);
4439: }
4440: #endif
4441: supportNew[0] = (c - cStart)*8 + 0+4;
4442: supportNew[1] = (c - cStart)*8 + 3+4;
4443: DMPlexSetSupport(rdm, newp, supportNew);
4444: #if defined(PETSC_USE_DEBUG)
4445: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4446: for (p = 0; p < 2; ++p) {
4447: 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);
4448: }
4449: #endif
4450: ++newp;
4451: /* Face F: {c, a, f} */
4452: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
4453: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4454: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4455: orntNew[1] = 0;
4456: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
4457: orntNew[2] = ornt[2] < 0 ? 0 : -2;
4458: DMPlexSetCone(rdm, newp, coneNew);
4459: DMPlexSetConeOrientation(rdm, newp, orntNew);
4460: #if defined(PETSC_USE_DEBUG)
4461: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4462: for (p = 0; p < 3; ++p) {
4463: 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);
4464: }
4465: #endif
4466: supportNew[0] = (c - cStart)*8 + 0+4;
4467: supportNew[1] = (c - cStart)*8 + 2+4;
4468: DMPlexSetSupport(rdm, newp, supportNew);
4469: #if defined(PETSC_USE_DEBUG)
4470: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4471: for (p = 0; p < 2; ++p) {
4472: 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);
4473: }
4474: #endif
4475: ++newp;
4476: /* Face G: {e, a, f} */
4477: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
4478: orntNew[0] = ornt[1] < 0 ? -2 : 0;
4479: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4480: orntNew[1] = 0;
4481: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
4482: orntNew[2] = ornt[3] < 0 ? 0 : -2;
4483: DMPlexSetCone(rdm, newp, coneNew);
4484: DMPlexSetConeOrientation(rdm, newp, orntNew);
4485: #if defined(PETSC_USE_DEBUG)
4486: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4487: for (p = 0; p < 3; ++p) {
4488: 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);
4489: }
4490: #endif
4491: supportNew[0] = (c - cStart)*8 + 1+4;
4492: supportNew[1] = (c - cStart)*8 + 3+4;
4493: DMPlexSetSupport(rdm, newp, supportNew);
4494: #if defined(PETSC_USE_DEBUG)
4495: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4496: for (p = 0; p < 2; ++p) {
4497: 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);
4498: }
4499: #endif
4500: ++newp;
4501: /* Face H: {a, b, f} */
4502: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
4503: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4504: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
4505: orntNew[1] = ornt[3] < 0 ? 0 : -2;
4506: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4507: orntNew[2] = -2;
4508: DMPlexSetCone(rdm, newp, coneNew);
4509: DMPlexSetConeOrientation(rdm, newp, orntNew);
4510: #if defined(PETSC_USE_DEBUG)
4511: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4512: for (p = 0; p < 3; ++p) {
4513: 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);
4514: }
4515: #endif
4516: supportNew[0] = (c - cStart)*8 + 1+4;
4517: supportNew[1] = (c - cStart)*8 + 2+4;
4518: DMPlexSetSupport(rdm, newp, supportNew);
4519: #if defined(PETSC_USE_DEBUG)
4520: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4521: for (p = 0; p < 2; ++p) {
4522: 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);
4523: }
4524: #endif
4525: ++newp;
4526: }
4527: /* Hybrid split faces have 4 edges and same cells */
4528: for (f = fMax; f < fEnd; ++f) {
4529: const PetscInt *cone, *ornt, *support;
4530: PetscInt coneNew[4], orntNew[4];
4531: PetscInt supportNew[2], size, s, c;
4533: DMPlexGetCone(dm, f, &cone);
4534: DMPlexGetConeOrientation(dm, f, &ornt);
4535: DMPlexGetSupportSize(dm, f, &size);
4536: DMPlexGetSupport(dm, f, &support);
4537: for (r = 0; r < 2; ++r) {
4538: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
4540: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
4541: orntNew[0] = ornt[0];
4542: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
4543: orntNew[1] = ornt[1];
4544: coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
4545: orntNew[2+r] = 0;
4546: coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
4547: orntNew[3-r] = 0;
4548: DMPlexSetCone(rdm, newp, coneNew);
4549: DMPlexSetConeOrientation(rdm, newp, orntNew);
4550: #if defined(PETSC_USE_DEBUG)
4551: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
4552: for (p = 0; p < 2; ++p) {
4553: 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);
4554: }
4555: for (p = 2; p < 4; ++p) {
4556: 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);
4557: }
4558: #endif
4559: for (s = 0; s < size; ++s) {
4560: const PetscInt *coneCell, *orntCell, *fornt;
4561: PetscInt o, of;
4563: DMPlexGetCone(dm, support[s], &coneCell);
4564: DMPlexGetConeOrientation(dm, support[s], &orntCell);
4565: o = orntCell[0] < 0 ? -1 : 1;
4566: for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
4567: if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]);
4568: DMPlexGetConeOrientation(dm, coneCell[0], &fornt);
4569: of = fornt[c-2] < 0 ? -1 : 1;
4570: supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3;
4571: }
4572: DMPlexSetSupport(rdm, newp, supportNew);
4573: #if defined(PETSC_USE_DEBUG)
4574: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
4575: for (p = 0; p < size; ++p) {
4576: 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);
4577: }
4578: #endif
4579: }
4580: }
4581: /* Hybrid cell faces have 4 edges and 2 cells */
4582: for (c = cMax; c < cEnd; ++c) {
4583: PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
4584: const PetscInt *cone, *ornt;
4585: PetscInt coneNew[4], orntNew[4];
4586: PetscInt supportNew[2];
4588: DMPlexGetCone(dm, c, &cone);
4589: DMPlexGetConeOrientation(dm, c, &ornt);
4590: for (r = 0; r < 3; ++r) {
4591: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
4592: orntNew[0] = 0;
4593: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
4594: orntNew[1] = 0;
4595: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
4596: orntNew[2] = 0;
4597: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax);
4598: orntNew[3] = 0;
4599: DMPlexSetCone(rdm, newp+r, coneNew);
4600: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
4601: #if defined(PETSC_USE_DEBUG)
4602: 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);
4603: for (p = 0; p < 2; ++p) {
4604: 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);
4605: }
4606: for (p = 2; p < 4; ++p) {
4607: 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);
4608: }
4609: #endif
4610: supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
4611: supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
4612: DMPlexSetSupport(rdm, newp+r, supportNew);
4613: #if defined(PETSC_USE_DEBUG)
4614: 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);
4615: for (p = 0; p < 2; ++p) {
4616: 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);
4617: }
4618: #endif
4619: }
4620: }
4621: /* Interior split edges have 2 vertices and the same faces as the parent */
4622: for (e = eStart; e < eMax; ++e) {
4623: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
4625: for (r = 0; r < 2; ++r) {
4626: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
4627: const PetscInt *cone, *ornt, *support;
4628: PetscInt coneNew[2], coneSize, c, supportSize, s;
4630: DMPlexGetCone(dm, e, &cone);
4631: coneNew[0] = vStartNew + (cone[0] - vStart);
4632: coneNew[1] = vStartNew + (cone[1] - vStart);
4633: coneNew[(r+1)%2] = newv;
4634: DMPlexSetCone(rdm, newp, coneNew);
4635: #if defined(PETSC_USE_DEBUG)
4636: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4637: for (p = 0; p < 2; ++p) {
4638: 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);
4639: }
4640: #endif
4641: DMPlexGetSupportSize(dm, e, &supportSize);
4642: DMPlexGetSupport(dm, e, &support);
4643: for (s = 0; s < supportSize; ++s) {
4644: DMPlexGetConeSize(dm, support[s], &coneSize);
4645: DMPlexGetCone(dm, support[s], &cone);
4646: DMPlexGetConeOrientation(dm, support[s], &ornt);
4647: for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
4648: if (support[s] < fMax) {
4649: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
4650: } else {
4651: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
4652: }
4653: }
4654: DMPlexSetSupport(rdm, newp, supportRef);
4655: #if defined(PETSC_USE_DEBUG)
4656: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4657: for (p = 0; p < supportSize; ++p) {
4658: 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);
4659: }
4660: #endif
4661: }
4662: }
4663: /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
4664: for (f = fStart; f < fMax; ++f) {
4665: const PetscInt *cone, *ornt, *support;
4666: PetscInt coneSize, supportSize, s;
4668: DMPlexGetSupportSize(dm, f, &supportSize);
4669: DMPlexGetSupport(dm, f, &support);
4670: for (r = 0; r < 3; ++r) {
4671: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
4672: PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
4673: PetscInt fint[24] = { 1, 7, -1, -1, 0, 5,
4674: -1, -1, 1, 6, 0, 4,
4675: 2, 5, 3, 4, -1, -1,
4676: -1, -1, 3, 6, 2, 7};
4678: DMPlexGetCone(dm, f, &cone);
4679: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
4680: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
4681: DMPlexSetCone(rdm, newp, coneNew);
4682: #if defined(PETSC_USE_DEBUG)
4683: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4684: for (p = 0; p < 2; ++p) {
4685: 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);
4686: }
4687: #endif
4688: supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
4689: supportRef[1] = fStartNew + (f - fStart)*4 + 3;
4690: for (s = 0; s < supportSize; ++s) {
4691: DMPlexGetConeSize(dm, support[s], &coneSize);
4692: DMPlexGetCone(dm, support[s], &cone);
4693: DMPlexGetConeOrientation(dm, support[s], &ornt);
4694: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
4695: if (support[s] < cMax) {
4696: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4697: er = GetTriMidEdgeInverse_Static(ornt[c], r);
4698: if (er == eint[c]) {
4699: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
4700: } else {
4701: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
4702: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
4703: }
4704: } else {
4705: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
4706: }
4707: }
4708: DMPlexSetSupport(rdm, newp, supportRef);
4709: #if defined(PETSC_USE_DEBUG)
4710: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4711: for (p = 0; p < intFaces; ++p) {
4712: 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);
4713: }
4714: #endif
4715: }
4716: }
4717: /* Interior cell edges have 2 vertices and 4 faces */
4718: for (c = cStart; c < cMax; ++c) {
4719: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4720: const PetscInt *cone, *ornt, *fcone;
4721: PetscInt coneNew[2], supportNew[4], find;
4723: DMPlexGetCone(dm, c, &cone);
4724: DMPlexGetConeOrientation(dm, c, &ornt);
4725: DMPlexGetCone(dm, cone[0], &fcone);
4726: find = GetTriEdge_Static(ornt[0], 0);
4727: coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
4728: DMPlexGetCone(dm, cone[2], &fcone);
4729: find = GetTriEdge_Static(ornt[2], 1);
4730: coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
4731: DMPlexSetCone(rdm, newp, coneNew);
4732: #if defined(PETSC_USE_DEBUG)
4733: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4734: for (p = 0; p < 2; ++p) {
4735: 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);
4736: }
4737: #endif
4738: supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
4739: supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
4740: supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
4741: supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
4742: DMPlexSetSupport(rdm, newp, supportNew);
4743: #if defined(PETSC_USE_DEBUG)
4744: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4745: for (p = 0; p < 4; ++p) {
4746: 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);
4747: }
4748: #endif
4749: }
4750: /* Hybrid edges have two vertices and the same faces */
4751: for (e = eMax; e < eEnd; ++e) {
4752: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
4753: const PetscInt *cone, *support, *fcone;
4754: PetscInt coneNew[2], size, fsize, s;
4756: DMPlexGetCone(dm, e, &cone);
4757: DMPlexGetSupportSize(dm, e, &size);
4758: DMPlexGetSupport(dm, e, &support);
4759: coneNew[0] = vStartNew + (cone[0] - vStart);
4760: coneNew[1] = vStartNew + (cone[1] - vStart);
4761: DMPlexSetCone(rdm, newp, coneNew);
4762: #if defined(PETSC_USE_DEBUG)
4763: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4764: for (p = 0; p < 2; ++p) {
4765: 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);
4766: }
4767: #endif
4768: for (s = 0; s < size; ++s) {
4769: DMPlexGetConeSize(dm, support[s], &fsize);
4770: DMPlexGetCone(dm, support[s], &fcone);
4771: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
4772: if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]);
4773: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
4774: }
4775: DMPlexSetSupport(rdm, newp, supportRef);
4776: #if defined(PETSC_USE_DEBUG)
4777: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4778: for (p = 0; p < size; ++p) {
4779: 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);
4780: }
4781: #endif
4782: }
4783: /* Hybrid face edges have 2 vertices and 2+2*cells faces */
4784: for (f = fMax; f < fEnd; ++f) {
4785: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
4786: const PetscInt *cone, *support, *ccone, *cornt;
4787: PetscInt coneNew[2], size, csize, s;
4789: DMPlexGetCone(dm, f, &cone);
4790: DMPlexGetSupportSize(dm, f, &size);
4791: DMPlexGetSupport(dm, f, &support);
4792: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
4793: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
4794: DMPlexSetCone(rdm, newp, coneNew);
4795: #if defined(PETSC_USE_DEBUG)
4796: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4797: for (p = 0; p < 2; ++p) {
4798: 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);
4799: }
4800: #endif
4801: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
4802: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
4803: for (s = 0; s < size; ++s) {
4804: DMPlexGetConeSize(dm, support[s], &csize);
4805: DMPlexGetCone(dm, support[s], &ccone);
4806: DMPlexGetConeOrientation(dm, support[s], &cornt);
4807: for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
4808: 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]);
4809: supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
4810: supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
4811: }
4812: DMPlexSetSupport(rdm, newp, supportRef);
4813: #if defined(PETSC_USE_DEBUG)
4814: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4815: for (p = 0; p < 2+size*2; ++p) {
4816: 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);
4817: }
4818: #endif
4819: }
4820: /* Interior vertices have identical supports */
4821: for (v = vStart; v < vEnd; ++v) {
4822: const PetscInt newp = vStartNew + (v - vStart);
4823: const PetscInt *support, *cone;
4824: PetscInt size, s;
4826: DMPlexGetSupportSize(dm, v, &size);
4827: DMPlexGetSupport(dm, v, &support);
4828: for (s = 0; s < size; ++s) {
4829: PetscInt r = 0;
4831: DMPlexGetCone(dm, support[s], &cone);
4832: if (cone[1] == v) r = 1;
4833: if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4834: else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
4835: }
4836: DMPlexSetSupport(rdm, newp, supportRef);
4837: #if defined(PETSC_USE_DEBUG)
4838: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
4839: for (p = 0; p < size; ++p) {
4840: 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);
4841: }
4842: #endif
4843: }
4844: /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
4845: for (e = eStart; e < eMax; ++e) {
4846: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
4847: const PetscInt *cone, *support;
4848: PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
4850: DMPlexGetSupportSize(dm, e, &size);
4851: DMPlexGetSupport(dm, e, &support);
4852: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4853: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4854: for (s = 0; s < size; ++s) {
4855: PetscInt r = 0;
4857: if (support[s] < fMax) {
4858: DMPlexGetConeSize(dm, support[s], &coneSize);
4859: DMPlexGetCone(dm, support[s], &cone);
4860: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
4861: supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
4862: supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
4863: faceSize += 2;
4864: } else {
4865: supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
4866: ++faceSize;
4867: }
4868: }
4869: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
4870: for (s = 0; s < starSize*2; s += 2) {
4871: const PetscInt *cone, *ornt;
4872: PetscInt e01, e23;
4874: if ((star[s] >= cStart) && (star[s] < cMax)) {
4875: /* Check edge 0-1 */
4876: DMPlexGetCone(dm, star[s], &cone);
4877: DMPlexGetConeOrientation(dm, star[s], &ornt);
4878: DMPlexGetCone(dm, cone[0], &cone);
4879: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
4880: /* Check edge 2-3 */
4881: DMPlexGetCone(dm, star[s], &cone);
4882: DMPlexGetConeOrientation(dm, star[s], &ornt);
4883: DMPlexGetCone(dm, cone[2], &cone);
4884: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
4885: if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
4886: }
4887: }
4888: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
4889: DMPlexSetSupport(rdm, newp, supportRef);
4890: #if defined(PETSC_USE_DEBUG)
4891: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
4892: for (p = 0; p < 2+faceSize+cellSize; ++p) {
4893: 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);
4894: }
4895: #endif
4896: }
4897: PetscFree(supportRef);
4898: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
4899: break;
4900: case REFINER_SIMPLEX_TO_HEX_3D:
4901: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
4902: /* All cells have 6 faces */
4903: for (c = cStart; c < cEnd; ++c) {
4904: const PetscInt newp = cStartNew + (c - cStart)*4;
4905: const PetscInt *cone, *ornt;
4906: PetscInt coneNew[6];
4907: PetscInt orntNew[6];
4909: DMPlexGetCone(dm, c, &cone);
4910: DMPlexGetConeOrientation(dm, c, &ornt);
4911: /* A hex */
4912: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
4913: orntNew[0] = ornt[0] < 0 ? -1 : 1;
4914: coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */
4915: orntNew[1] = -4;
4916: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */
4917: orntNew[2] = ornt[2] < 0 ? -1 : 1;
4918: coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */
4919: orntNew[3] = -1;
4920: coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */
4921: orntNew[4] = 0;
4922: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */
4923: orntNew[5] = ornt[1] < 0 ? -1 : 1;
4924: DMPlexSetCone(rdm, newp+0, coneNew);
4925: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
4926: #if defined(PETSC_USE_DEBUG)
4927: 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);
4928: for (p = 0; p < 6; ++p) {
4929: 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);
4930: }
4931: #endif
4932: /* B hex */
4933: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
4934: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4935: coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */
4936: orntNew[1] = 0;
4937: coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */
4938: orntNew[2] = 0;
4939: coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */
4940: orntNew[3] = ornt[3] < 0 ? -2 : 0;
4941: coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */
4942: orntNew[4] = 0;
4943: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */
4944: orntNew[5] = ornt[1] < 0 ? -4 : 2;
4945: DMPlexSetCone(rdm, newp+1, coneNew);
4946: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
4947: #if defined(PETSC_USE_DEBUG)
4948: 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);
4949: for (p = 0; p < 6; ++p) {
4950: 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);
4951: }
4952: #endif
4953: /* C hex */
4954: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
4955: orntNew[0] = ornt[0] < 0 ? -4 : 2;
4956: coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */
4957: orntNew[1] = -4;
4958: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */
4959: orntNew[2] = ornt[2] < 0 ? -2 : 0;
4960: coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */
4961: orntNew[3] = -1;
4962: coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */
4963: orntNew[4] = ornt[3] < 0 ? -1 : 1;
4964: coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */
4965: orntNew[5] = -4;
4966: DMPlexSetCone(rdm, newp+2, coneNew);
4967: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
4968: #if defined(PETSC_USE_DEBUG)
4969: 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);
4970: for (p = 0; p < 6; ++p) {
4971: 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);
4972: }
4973: #endif
4974: /* D hex */
4975: coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */
4976: orntNew[0] = 0;
4977: coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */
4978: orntNew[1] = ornt[3] < 0 ? -1 : 1;
4979: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */
4980: orntNew[2] = ornt[2] < 0 ? -4 : 2;
4981: coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */
4982: orntNew[3] = -1;
4983: coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */
4984: orntNew[4] = 0;
4985: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */
4986: orntNew[5] = ornt[1] < 0 ? -2 : 0;
4987: DMPlexSetCone(rdm, newp+3, coneNew);
4988: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
4989: #if defined(PETSC_USE_DEBUG)
4990: 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);
4991: for (p = 0; p < 6; ++p) {
4992: 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);
4993: }
4994: #endif
4995: }
4996: /* Split faces have 4 edges and the same cells as the parent */
4997: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
4998: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
4999: for (f = fStart; f < fEnd; ++f) {
5000: const PetscInt newp = fStartNew + (f - fStart)*3;
5001: const PetscInt *cone, *ornt, *support;
5002: PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s;
5004: DMPlexGetCone(dm, f, &cone);
5005: DMPlexGetConeOrientation(dm, f, &ornt);
5006: /* A quad */
5007: coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
5008: orntNew[0] = ornt[2];
5009: coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
5010: orntNew[1] = ornt[0];
5011: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
5012: orntNew[2] = 0;
5013: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
5014: orntNew[3] = -2;
5015: DMPlexSetCone(rdm, newp+0, coneNew);
5016: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5017: #if defined(PETSC_USE_DEBUG)
5018: 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);
5019: for (p = 0; p < 4; ++p) {
5020: 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);
5021: }
5022: #endif
5023: /* B quad */
5024: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
5025: orntNew[0] = ornt[0];
5026: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
5027: orntNew[1] = ornt[1];
5028: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
5029: orntNew[2] = 0;
5030: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
5031: orntNew[3] = -2;
5032: DMPlexSetCone(rdm, newp+1, coneNew);
5033: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5034: #if defined(PETSC_USE_DEBUG)
5035: 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);
5036: for (p = 0; p < 4; ++p) {
5037: 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);
5038: }
5039: #endif
5040: /* C quad */
5041: coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
5042: orntNew[0] = ornt[1];
5043: coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
5044: orntNew[1] = ornt[2];
5045: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
5046: orntNew[2] = 0;
5047: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
5048: orntNew[3] = -2;
5049: DMPlexSetCone(rdm, newp+2, coneNew);
5050: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5051: #if defined(PETSC_USE_DEBUG)
5052: 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);
5053: for (p = 0; p < 4; ++p) {
5054: 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);
5055: }
5056: #endif
5057: DMPlexGetSupportSize(dm, f, &supportSize);
5058: DMPlexGetSupport(dm, f, &support);
5059: for (r = 0; r < 3; ++r) {
5060: for (s = 0; s < supportSize; ++s) {
5061: PetscInt subf;
5062: DMPlexGetConeSize(dm, support[s], &coneSize);
5063: DMPlexGetCone(dm, support[s], &cone);
5064: DMPlexGetConeOrientation(dm, support[s], &ornt);
5065: for (c = 0; c < coneSize; ++c) {
5066: if (cone[c] == f) break;
5067: }
5068: subf = GetTriSubfaceInverse_Static(ornt[c], r);
5069: supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf];
5070: }
5071: DMPlexSetSupport(rdm, newp+r, supportRef);
5072: #if defined(PETSC_USE_DEBUG)
5073: 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);
5074: for (p = 0; p < supportSize; ++p) {
5075: 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);
5076: }
5077: #endif
5078: }
5079: }
5080: /* Interior faces have 4 edges and 2 cells */
5081: for (c = cStart; c < cEnd; ++c) {
5082: PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6;
5083: const PetscInt *cone, *ornt;
5084: PetscInt coneNew[4], orntNew[4];
5085: PetscInt supportNew[2];
5087: DMPlexGetCone(dm, c, &cone);
5088: DMPlexGetConeOrientation(dm, c, &ornt);
5089: /* Face {a, g, m, h} */
5090: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
5091: orntNew[0] = 0;
5092: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5093: orntNew[1] = 0;
5094: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5095: orntNew[2] = -2;
5096: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
5097: orntNew[3] = -2;
5098: DMPlexSetCone(rdm, newp, coneNew);
5099: DMPlexSetConeOrientation(rdm, newp, orntNew);
5100: #if defined(PETSC_USE_DEBUG)
5101: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5102: for (p = 0; p < 4; ++p) {
5103: 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);
5104: }
5105: #endif
5106: supportNew[0] = (c - cStart)*4 + 0;
5107: supportNew[1] = (c - cStart)*4 + 1;
5108: DMPlexSetSupport(rdm, newp, supportNew);
5109: #if defined(PETSC_USE_DEBUG)
5110: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5111: for (p = 0; p < 2; ++p) {
5112: 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);
5113: }
5114: #endif
5115: ++newp;
5116: /* Face {g, b, l , m} */
5117: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
5118: orntNew[0] = -2;
5119: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0);
5120: orntNew[1] = 0;
5121: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5122: orntNew[2] = 0;
5123: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5124: orntNew[3] = -2;
5125: DMPlexSetCone(rdm, newp, coneNew);
5126: DMPlexSetConeOrientation(rdm, newp, orntNew);
5127: #if defined(PETSC_USE_DEBUG)
5128: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5129: for (p = 0; p < 4; ++p) {
5130: 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);
5131: }
5132: #endif
5133: supportNew[0] = (c - cStart)*4 + 1;
5134: supportNew[1] = (c - cStart)*4 + 2;
5135: DMPlexSetSupport(rdm, newp, supportNew);
5136: #if defined(PETSC_USE_DEBUG)
5137: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5138: for (p = 0; p < 2; ++p) {
5139: 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);
5140: }
5141: #endif
5142: ++newp;
5143: /* Face {c, g, m, i} */
5144: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
5145: orntNew[0] = 0;
5146: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5147: orntNew[1] = 0;
5148: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5149: orntNew[2] = -2;
5150: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0);
5151: orntNew[3] = -2;
5152: DMPlexSetCone(rdm, newp, coneNew);
5153: DMPlexSetConeOrientation(rdm, newp, orntNew);
5154: #if defined(PETSC_USE_DEBUG)
5155: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5156: for (p = 0; p < 4; ++p) {
5157: 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);
5158: }
5159: #endif
5160: supportNew[0] = (c - cStart)*4 + 0;
5161: supportNew[1] = (c - cStart)*4 + 2;
5162: DMPlexSetSupport(rdm, newp, supportNew);
5163: #if defined(PETSC_USE_DEBUG)
5164: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5165: for (p = 0; p < 2; ++p) {
5166: 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);
5167: }
5168: #endif
5169: ++newp;
5170: /* Face {d, h, m, i} */
5171: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
5172: orntNew[0] = 0;
5173: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5174: orntNew[1] = 0;
5175: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5176: orntNew[2] = -2;
5177: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2);
5178: orntNew[3] = -2;
5179: DMPlexSetCone(rdm, newp, coneNew);
5180: DMPlexSetConeOrientation(rdm, newp, orntNew);
5181: #if defined(PETSC_USE_DEBUG)
5182: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5183: for (p = 0; p < 4; ++p) {
5184: 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);
5185: }
5186: #endif
5187: supportNew[0] = (c - cStart)*4 + 0;
5188: supportNew[1] = (c - cStart)*4 + 3;
5189: DMPlexSetSupport(rdm, newp, supportNew);
5190: #if defined(PETSC_USE_DEBUG)
5191: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5192: for (p = 0; p < 2; ++p) {
5193: 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);
5194: }
5195: #endif
5196: ++newp;
5197: /* Face {h, m, l, e} */
5198: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5199: orntNew[0] = 0;
5200: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5201: orntNew[1] = -2;
5202: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1);
5203: orntNew[2] = -2;
5204: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
5205: orntNew[3] = 0;
5206: DMPlexSetCone(rdm, newp, coneNew);
5207: DMPlexSetConeOrientation(rdm, newp, orntNew);
5208: #if defined(PETSC_USE_DEBUG)
5209: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5210: for (p = 0; p < 4; ++p) {
5211: 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);
5212: }
5213: #endif
5214: supportNew[0] = (c - cStart)*4 + 1;
5215: supportNew[1] = (c - cStart)*4 + 3;
5216: DMPlexSetSupport(rdm, newp, supportNew);
5217: #if defined(PETSC_USE_DEBUG)
5218: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5219: for (p = 0; p < 2; ++p) {
5220: 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);
5221: }
5222: #endif
5223: ++newp;
5224: /* Face {i, m, l, f} */
5225: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5226: orntNew[0] = 0;
5227: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5228: orntNew[1] = -2;
5229: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2);
5230: orntNew[2] = -2;
5231: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1);
5232: orntNew[3] = 0;
5233: DMPlexSetCone(rdm, newp, coneNew);
5234: DMPlexSetConeOrientation(rdm, newp, orntNew);
5235: #if defined(PETSC_USE_DEBUG)
5236: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5237: for (p = 0; p < 4; ++p) {
5238: 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);
5239: }
5240: #endif
5241: supportNew[0] = (c - cStart)*4 + 2;
5242: supportNew[1] = (c - cStart)*4 + 3;
5243: DMPlexSetSupport(rdm, newp, supportNew);
5244: #if defined(PETSC_USE_DEBUG)
5245: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5246: for (p = 0; p < 2; ++p) {
5247: 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);
5248: }
5249: #endif
5250: ++newp;
5251: }
5252: /* Split Edges have 2 vertices and the same faces as the parent */
5253: for (e = eStart; e < eEnd; ++e) {
5254: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
5256: for (r = 0; r < 2; ++r) {
5257: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
5258: const PetscInt *cone, *ornt, *support;
5259: PetscInt coneNew[2], coneSize, c, supportSize, s;
5261: DMPlexGetCone(dm, e, &cone);
5262: coneNew[0] = vStartNew + (cone[0] - vStart);
5263: coneNew[1] = vStartNew + (cone[1] - vStart);
5264: coneNew[(r+1)%2] = newv;
5265: DMPlexSetCone(rdm, newp, coneNew);
5266: #if defined(PETSC_USE_DEBUG)
5267: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5268: for (p = 0; p < 2; ++p) {
5269: 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);
5270: }
5271: #endif
5272: DMPlexGetSupportSize(dm, e, &supportSize);
5273: DMPlexGetSupport(dm, e, &support);
5274: for (s = 0; s < supportSize; ++s) {
5275: DMPlexGetConeSize(dm, support[s], &coneSize);
5276: DMPlexGetCone(dm, support[s], &cone);
5277: DMPlexGetConeOrientation(dm, support[s], &ornt);
5278: for (c = 0; c < coneSize; ++c) {
5279: if (cone[c] == e) break;
5280: }
5281: supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3;
5282: }
5283: DMPlexSetSupport(rdm, newp, supportRef);
5284: #if defined(PETSC_USE_DEBUG)
5285: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5286: for (p = 0; p < supportSize; ++p) {
5287: 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);
5288: }
5289: #endif
5290: }
5291: }
5292: /* Face edges have 2 vertices and 2 + cell faces supports */
5293: for (f = fStart; f < fEnd; ++f) {
5294: const PetscInt *cone, *ornt, *support;
5295: PetscInt coneSize, supportSize, s;
5297: DMPlexGetSupportSize(dm, f, &supportSize);
5298: DMPlexGetSupport(dm, f, &support);
5299: for (r = 0; r < 3; ++r) {
5300: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
5301: PetscInt coneNew[2];
5302: PetscInt fint[4][3] = { {0, 1, 2},
5303: {3, 4, 0},
5304: {2, 5, 3},
5305: {1, 4, 5} };
5307: DMPlexGetCone(dm, f, &cone);
5308: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
5309: coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
5310: DMPlexSetCone(rdm, newp, coneNew);
5311: #if defined(PETSC_USE_DEBUG)
5312: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5313: for (p = 0; p < 2; ++p) {
5314: 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);
5315: }
5316: #endif
5317: supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3;
5318: supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3;
5319: for (s = 0; s < supportSize; ++s) {
5320: PetscInt er;
5321: DMPlexGetConeSize(dm, support[s], &coneSize);
5322: DMPlexGetCone(dm, support[s], &cone);
5323: DMPlexGetConeOrientation(dm, support[s], &ornt);
5324: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
5325: er = GetTriInteriorEdgeInverse_Static(ornt[c], r);
5326: supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er];
5327: }
5328: DMPlexSetSupport(rdm, newp, supportRef);
5329: #if defined(PETSC_USE_DEBUG)
5330: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5331: for (p = 0; p < supportSize + 2; ++p) {
5332: 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);
5333: }
5334: #endif
5335: }
5336: }
5337: /* Interior cell edges have 2 vertices and 3 faces */
5338: for (c = cStart; c < cEnd; ++c) {
5339: const PetscInt *cone;
5340: PetscInt fint[4][3] = { {0,1,2},
5341: {0,3,4},
5342: {2,3,5},
5343: {1,4,5} } ;
5345: DMPlexGetCone(dm, c, &cone);
5346: for (r = 0; r < 4; r++) {
5347: PetscInt coneNew[2], supportNew[3];
5348: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
5350: coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
5351: coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart;
5352: DMPlexSetCone(rdm, newp, coneNew);
5353: #if defined(PETSC_USE_DEBUG)
5354: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5355: for (p = 0; p < 2; ++p) {
5356: 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);
5357: }
5358: #endif
5359: supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0];
5360: supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1];
5361: supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2];
5362: DMPlexSetSupport(rdm, newp, supportNew);
5363: #if defined(PETSC_USE_DEBUG)
5364: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5365: for (p = 0; p < 3; ++p) {
5366: 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);
5367: }
5368: #endif
5369: }
5370: }
5371: /* Old vertices have identical supports */
5372: for (v = vStart; v < vEnd; ++v) {
5373: const PetscInt newp = vStartNew + (v - vStart);
5374: const PetscInt *support, *cone;
5375: PetscInt size, s;
5377: DMPlexGetSupportSize(dm, v, &size);
5378: DMPlexGetSupport(dm, v, &support);
5379: for (s = 0; s < size; ++s) {
5380: PetscInt r = 0;
5382: DMPlexGetCone(dm, support[s], &cone);
5383: if (cone[1] == v) r = 1;
5384: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
5385: }
5386: DMPlexSetSupport(rdm, newp, supportRef);
5387: #if defined(PETSC_USE_DEBUG)
5388: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5389: for (p = 0; p < size; ++p) {
5390: 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);
5391: }
5392: #endif
5393: }
5394: /* Edge vertices have 2 + faces supports */
5395: for (e = eStart; e < eEnd; ++e) {
5396: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
5397: const PetscInt *cone, *support;
5398: PetscInt size, s;
5400: DMPlexGetSupportSize(dm, e, &size);
5401: DMPlexGetSupport(dm, e, &support);
5402: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
5403: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
5404: for (s = 0; s < size; ++s) {
5405: PetscInt r = 0, coneSize;
5407: DMPlexGetConeSize(dm, support[s], &coneSize);
5408: DMPlexGetCone(dm, support[s], &cone);
5409: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
5410: supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r;
5411: }
5412: DMPlexSetSupport(rdm, newp, supportRef);
5413: #if defined(PETSC_USE_DEBUG)
5414: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5415: for (p = 0; p < 2+size; ++p) {
5416: 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);
5417: }
5418: #endif
5419: }
5420: /* Face vertices have 3 + cells supports */
5421: for (f = fStart; f < fEnd; ++f) {
5422: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
5423: const PetscInt *cone, *support;
5424: PetscInt size, s;
5426: DMPlexGetSupportSize(dm, f, &size);
5427: DMPlexGetSupport(dm, f, &support);
5428: supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
5429: supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
5430: supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
5431: for (s = 0; s < size; ++s) {
5432: PetscInt r = 0, coneSize;
5434: DMPlexGetConeSize(dm, support[s], &coneSize);
5435: DMPlexGetCone(dm, support[s], &cone);
5436: for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;}
5437: supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r;
5438: }
5439: DMPlexSetSupport(rdm, newp, supportRef);
5440: #if defined(PETSC_USE_DEBUG)
5441: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5442: for (p = 0; p < 3+size; ++p) {
5443: 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);
5444: }
5445: #endif
5446: }
5447: /* Interior cell vertices have 4 supports */
5448: for (c = cStart; c < cEnd; ++c) {
5449: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart;
5450: supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5451: supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5452: supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5453: supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5454: DMPlexSetSupport(rdm, newp, supportRef);
5455: #if defined(PETSC_USE_DEBUG)
5456: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5457: for (p = 0; p < 4; ++p) {
5458: 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);
5459: }
5460: #endif
5461: }
5462: PetscFree(supportRef);
5463: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
5464: break;
5465: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
5466: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
5467: cMax = PetscMin(cEnd, cMax);
5468: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
5469: fMax = PetscMin(fEnd, fMax);
5470: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
5471: eMax = PetscMin(eEnd, eMax);
5472: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
5473: /* All cells have 6 faces */
5474: for (c = cStart; c < cMax; ++c) {
5475: const PetscInt newp = cStartNew + (c - cStart)*4;
5476: const PetscInt *cone, *ornt;
5477: PetscInt coneNew[6];
5478: PetscInt orntNew[6];
5480: DMPlexGetCone(dm, c, &cone);
5481: #if defined(PETSC_USE_DEBUG)
5482: for (p = 0; p < 4; ++p) {
5483: 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);
5484: }
5485: #endif
5486: DMPlexGetConeOrientation(dm, c, &ornt);
5487: /* A hex */
5488: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
5489: orntNew[0] = ornt[0] < 0 ? -1 : 1;
5490: coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* T */
5491: orntNew[1] = -4;
5492: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */
5493: orntNew[2] = ornt[2] < 0 ? -1 : 1;
5494: coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* K */
5495: orntNew[3] = -1;
5496: coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* R */
5497: orntNew[4] = 0;
5498: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */
5499: orntNew[5] = ornt[1] < 0 ? -1 : 1;
5500: DMPlexSetCone(rdm, newp+0, coneNew);
5501: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5502: #if defined(PETSC_USE_DEBUG)
5503: 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);
5504: for (p = 0; p < 6; ++p) {
5505: 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);
5506: }
5507: #endif
5508: /* B hex */
5509: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
5510: orntNew[0] = ornt[0] < 0 ? -2 : 0;
5511: coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* T */
5512: orntNew[1] = 0;
5513: coneNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* F */
5514: orntNew[2] = 0;
5515: coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */
5516: orntNew[3] = ornt[3] < 0 ? -2 : 0;
5517: coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* R */
5518: orntNew[4] = 0;
5519: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */
5520: orntNew[5] = ornt[1] < 0 ? -4 : 2;
5521: DMPlexSetCone(rdm, newp+1, coneNew);
5522: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5523: #if defined(PETSC_USE_DEBUG)
5524: 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);
5525: for (p = 0; p < 6; ++p) {
5526: 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);
5527: }
5528: #endif
5529: /* C hex */
5530: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
5531: orntNew[0] = ornt[0] < 0 ? -4 : 2;
5532: coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* T */
5533: orntNew[1] = -4;
5534: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */
5535: orntNew[2] = ornt[2] < 0 ? -2 : 0;
5536: coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* K */
5537: orntNew[3] = -1;
5538: coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */
5539: orntNew[4] = ornt[3] < 0 ? -1 : 1;
5540: coneNew[5] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* L */
5541: orntNew[5] = -4;
5542: DMPlexSetCone(rdm, newp+2, coneNew);
5543: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5544: #if defined(PETSC_USE_DEBUG)
5545: 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);
5546: for (p = 0; p < 6; ++p) {
5547: 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);
5548: }
5549: #endif
5550: /* D hex */
5551: coneNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* B */
5552: orntNew[0] = 0;
5553: coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */
5554: orntNew[1] = ornt[3] < 0 ? -1 : 1;
5555: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */
5556: orntNew[2] = ornt[2] < 0 ? -4 : 2;
5557: coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* K */
5558: orntNew[3] = -1;
5559: coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* R */
5560: orntNew[4] = 0;
5561: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */
5562: orntNew[5] = ornt[1] < 0 ? -2 : 0;
5563: DMPlexSetCone(rdm, newp+3, coneNew);
5564: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
5565: #if defined(PETSC_USE_DEBUG)
5566: 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);
5567: for (p = 0; p < 6; ++p) {
5568: 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);
5569: }
5570: #endif
5571: }
5572: for (c = cMax; c < cEnd; ++c) {
5573: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3;
5574: const PetscInt *cone, *ornt, *fornt;
5575: PetscInt coneNew[6], orntNew[6];
5576: PetscInt o, of, cf;
5578: DMPlexGetCone(dm, c, &cone);
5579: #if defined(PETSC_USE_DEBUG)
5580: 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);
5581: 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);
5582: 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);
5583: 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);
5584: 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);
5585: #endif
5586: DMPlexGetConeOrientation(dm, c, &ornt);
5587: DMPlexGetConeOrientation(dm, cone[0], &fornt);
5588: o = ornt[0] < 0 ? -1 : 1;
5589: /* A hex */
5590: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
5591: orntNew[0] = ornt[0] < 0 ? -1 : 1;
5592: coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* T */
5593: orntNew[1] = ornt[1] < 0 ? 1 : -1;
5594: cf = GetTriEdge_Static(ornt[0], 2);
5595: of = fornt[cf] < 0 ? -1 : 1;
5596: coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* F */
5597: orntNew[2] = o*of < 0 ? 0 : -1;
5598: coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* K */
5599: orntNew[3] = -1;
5600: coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* R */
5601: orntNew[4] = 0;
5602: cf = GetTriEdge_Static(ornt[0], 0);
5603: of = fornt[cf] < 0 ? -1 : 1;
5604: coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* L */
5605: orntNew[5] = o*of < 0 ? 1 : -4;
5606: DMPlexSetCone(rdm, newp+0, coneNew);
5607: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5608: #if defined(PETSC_USE_DEBUG)
5609: 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);
5610: for (p = 0; p < 6; ++p) {
5611: 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);
5612: }
5613: #endif
5614: /* B hex */
5615: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
5616: orntNew[0] = ornt[0] < 0 ? -2 : 0;
5617: coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* T */
5618: orntNew[1] = ornt[1] < 0 ? 2 : -4;
5619: coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* F */
5620: orntNew[2] = 0;
5621: cf = GetTriEdge_Static(ornt[0], 1);
5622: of = fornt[cf] < 0 ? -1 : 1;
5623: coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* K */
5624: orntNew[3] = o*of < 0 ? 0 : -1;
5625: coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* R */
5626: orntNew[4] = -1;
5627: cf = GetTriEdge_Static(ornt[0], 0);
5628: of = fornt[cf] < 0 ? -1 : 1;
5629: coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* L */
5630: orntNew[5] = o*of < 0 ? 1 : -4;
5631: DMPlexSetCone(rdm, newp+1, coneNew);
5632: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5633: #if defined(PETSC_USE_DEBUG)
5634: 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);
5635: for (p = 0; p < 6; ++p) {
5636: 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);
5637: }
5638: #endif
5639: /* C hex */
5640: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
5641: orntNew[0] = ornt[0] < 0 ? -4 : 2;
5642: coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* T */
5643: orntNew[1] = ornt[1] < 0 ? 0 : -2;
5644: cf = GetTriEdge_Static(ornt[0], 2);
5645: of = fornt[cf] < 0 ? -1 : 1;
5646: coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* F */
5647: orntNew[2] = o*of < 0 ? 0 : -1;
5648: coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* K */
5649: orntNew[3] = 0;
5650: cf = GetTriEdge_Static(ornt[0], 1);
5651: of = fornt[cf] < 0 ? -1 : 1;
5652: coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* R */
5653: orntNew[4] = o*of < 0 ? 0 : -1;
5654: coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* L */
5655: orntNew[5] = -4;
5656: DMPlexSetCone(rdm, newp+2, coneNew);
5657: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5658: #if defined(PETSC_USE_DEBUG)
5659: 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);
5660: for (p = 0; p < 6; ++p) {
5661: 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);
5662: }
5663: #endif
5664: }
5666: /* Split faces have 4 edges and the same cells as the parent */
5667: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
5668: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
5669: for (f = fStart; f < fMax; ++f) {
5670: const PetscInt newp = fStartNew + (f - fStart)*3;
5671: const PetscInt *cone, *ornt, *support;
5672: PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s;
5674: DMPlexGetCone(dm, f, &cone);
5675: #if defined(PETSC_USE_DEBUG)
5676: for (p = 0; p < 3; ++p) {
5677: 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);
5678: }
5679: #endif
5680: DMPlexGetConeOrientation(dm, f, &ornt);
5681: /* A quad */
5682: coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
5683: orntNew[0] = ornt[2];
5684: coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
5685: orntNew[1] = ornt[0];
5686: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
5687: orntNew[2] = 0;
5688: coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
5689: orntNew[3] = -2;
5690: DMPlexSetCone(rdm, newp+0, coneNew);
5691: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5692: #if defined(PETSC_USE_DEBUG)
5693: 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);
5694: for (p = 0; p < 4; ++p) {
5695: 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);
5696: }
5697: #endif
5698: /* B quad */
5699: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
5700: orntNew[0] = ornt[0];
5701: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
5702: orntNew[1] = ornt[1];
5703: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
5704: orntNew[2] = 0;
5705: coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
5706: orntNew[3] = -2;
5707: DMPlexSetCone(rdm, newp+1, coneNew);
5708: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5709: #if defined(PETSC_USE_DEBUG)
5710: 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);
5711: for (p = 0; p < 4; ++p) {
5712: 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);
5713: }
5714: #endif
5715: /* C quad */
5716: coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
5717: orntNew[0] = ornt[1];
5718: coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
5719: orntNew[1] = ornt[2];
5720: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
5721: orntNew[2] = 0;
5722: coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
5723: orntNew[3] = -2;
5724: DMPlexSetCone(rdm, newp+2, coneNew);
5725: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5726: #if defined(PETSC_USE_DEBUG)
5727: 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);
5728: for (p = 0; p < 4; ++p) {
5729: 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);
5730: }
5731: #endif
5732: DMPlexGetSupportSize(dm, f, &supportSize);
5733: DMPlexGetSupport(dm, f, &support);
5734: for (r = 0; r < 3; ++r) {
5735: for (s = 0; s < supportSize; ++s) {
5736: PetscInt subf;
5738: DMPlexGetConeSize(dm, support[s], &coneSize);
5739: 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);
5740: 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);
5741: DMPlexGetCone(dm, support[s], &cone);
5742: DMPlexGetConeOrientation(dm, support[s], &ornt);
5743: for (c = 0; c < coneSize; ++c) {
5744: if (cone[c] == f) break;
5745: }
5746: subf = GetTriSubfaceInverse_Static(ornt[c], r);
5747: if (coneSize == 4) {
5748: supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf];
5749: } else if (coneSize == 5) {
5750: 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);
5751: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + subf;
5752: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax);
5753: }
5754: DMPlexSetSupport(rdm, newp+r, supportRef);
5755: #if defined(PETSC_USE_DEBUG)
5756: 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);
5757: for (p = 0; p < supportSize; ++p) {
5758: 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);
5759: }
5760: #endif
5761: }
5762: }
5763: /* Interior faces have 4 edges and 2 cells */
5764: for (c = cStart; c < cMax; ++c) {
5765: PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6;
5766: const PetscInt *cone, *ornt;
5767: PetscInt coneNew[4], orntNew[4];
5768: PetscInt supportNew[2];
5770: DMPlexGetCone(dm, c, &cone);
5771: #if defined(PETSC_USE_DEBUG)
5772: for (p = 0; p < 4; ++p) {
5773: 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);
5774: }
5775: #endif
5776: DMPlexGetConeOrientation(dm, c, &ornt);
5777: /* Face {a, g, m, h} */
5778: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
5779: orntNew[0] = 0;
5780: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
5781: orntNew[1] = 0;
5782: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
5783: orntNew[2] = -2;
5784: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
5785: orntNew[3] = -2;
5786: DMPlexSetCone(rdm, newp, coneNew);
5787: DMPlexSetConeOrientation(rdm, newp, orntNew);
5788: #if defined(PETSC_USE_DEBUG)
5789: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5790: for (p = 0; p < 4; ++p) {
5791: 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);
5792: }
5793: #endif
5794: supportNew[0] = cStartNew + (c - cStart)*4 + 0;
5795: supportNew[1] = cStartNew + (c - cStart)*4 + 1;
5796: DMPlexSetSupport(rdm, newp, supportNew);
5797: #if defined(PETSC_USE_DEBUG)
5798: for (p = 0; p < 2; ++p) {
5799: 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);
5800: }
5801: #endif
5802: ++newp;
5803: /* Face {g, b, l , m} */
5804: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
5805: orntNew[0] = -2;
5806: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0);
5807: orntNew[1] = 0;
5808: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
5809: orntNew[2] = 0;
5810: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
5811: orntNew[3] = -2;
5812: DMPlexSetCone(rdm, newp, coneNew);
5813: DMPlexSetConeOrientation(rdm, newp, orntNew);
5814: #if defined(PETSC_USE_DEBUG)
5815: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5816: for (p = 0; p < 4; ++p) {
5817: 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);
5818: }
5819: #endif
5820: supportNew[0] = cStartNew + (c - cStart)*4 + 1;
5821: supportNew[1] = cStartNew + (c - cStart)*4 + 2;
5822: DMPlexSetSupport(rdm, newp, supportNew);
5823: #if defined(PETSC_USE_DEBUG)
5824: for (p = 0; p < 2; ++p) {
5825: 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);
5826: }
5827: #endif
5828: ++newp;
5829: /* Face {c, g, m, i} */
5830: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
5831: orntNew[0] = 0;
5832: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
5833: orntNew[1] = 0;
5834: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
5835: orntNew[2] = -2;
5836: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0);
5837: orntNew[3] = -2;
5838: DMPlexSetCone(rdm, newp, coneNew);
5839: DMPlexSetConeOrientation(rdm, newp, orntNew);
5840: #if defined(PETSC_USE_DEBUG)
5841: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5842: for (p = 0; p < 4; ++p) {
5843: 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);
5844: }
5845: #endif
5846: supportNew[0] = cStartNew + (c - cStart)*4 + 0;
5847: supportNew[1] = cStartNew + (c - cStart)*4 + 2;
5848: DMPlexSetSupport(rdm, newp, supportNew);
5849: #if defined(PETSC_USE_DEBUG)
5850: for (p = 0; p < 2; ++p) {
5851: 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);
5852: }
5853: #endif
5854: ++newp;
5855: /* Face {d, h, m, i} */
5856: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
5857: orntNew[0] = 0;
5858: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
5859: orntNew[1] = 0;
5860: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
5861: orntNew[2] = -2;
5862: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2);
5863: orntNew[3] = -2;
5864: DMPlexSetCone(rdm, newp, coneNew);
5865: DMPlexSetConeOrientation(rdm, newp, orntNew);
5866: #if defined(PETSC_USE_DEBUG)
5867: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5868: for (p = 0; p < 4; ++p) {
5869: 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);
5870: }
5871: #endif
5872: supportNew[0] = cStartNew + (c - cStart)*4 + 0;
5873: supportNew[1] = cStartNew + (c - cStart)*4 + 3;
5874: DMPlexSetSupport(rdm, newp, supportNew);
5875: #if defined(PETSC_USE_DEBUG)
5876: for (p = 0; p < 2; ++p) {
5877: 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);
5878: }
5879: #endif
5880: ++newp;
5881: /* Face {h, m, l, e} */
5882: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
5883: orntNew[0] = 0;
5884: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
5885: orntNew[1] = -2;
5886: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1);
5887: orntNew[2] = -2;
5888: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
5889: orntNew[3] = 0;
5890: DMPlexSetCone(rdm, newp, coneNew);
5891: DMPlexSetConeOrientation(rdm, newp, orntNew);
5892: #if defined(PETSC_USE_DEBUG)
5893: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5894: for (p = 0; p < 4; ++p) {
5895: 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);
5896: }
5897: #endif
5898: supportNew[0] = cStartNew + (c - cStart)*4 + 1;
5899: supportNew[1] = cStartNew + (c - cStart)*4 + 3;
5900: DMPlexSetSupport(rdm, newp, supportNew);
5901: #if defined(PETSC_USE_DEBUG)
5902: for (p = 0; p < 2; ++p) {
5903: 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);
5904: }
5905: #endif
5906: ++newp;
5907: /* Face {i, m, l, f} */
5908: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
5909: orntNew[0] = 0;
5910: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
5911: orntNew[1] = -2;
5912: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2);
5913: orntNew[2] = -2;
5914: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1);
5915: orntNew[3] = 0;
5916: DMPlexSetCone(rdm, newp, coneNew);
5917: DMPlexSetConeOrientation(rdm, newp, orntNew);
5918: #if defined(PETSC_USE_DEBUG)
5919: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5920: for (p = 0; p < 4; ++p) {
5921: 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);
5922: }
5923: #endif
5924: supportNew[0] = cStartNew + (c - cStart)*4 + 2;
5925: supportNew[1] = cStartNew + (c - cStart)*4 + 3;
5926: DMPlexSetSupport(rdm, newp, supportNew);
5927: #if defined(PETSC_USE_DEBUG)
5928: for (p = 0; p < 2; ++p) {
5929: 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);
5930: }
5931: #endif
5932: ++newp;
5933: }
5934: /* Hybrid split faces have 4 edges and same cells */
5935: for (f = fMax; f < fEnd; ++f) {
5936: const PetscInt *cone, *ornt, *support;
5937: PetscInt coneNew[4], orntNew[4];
5938: PetscInt size, s;
5939: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2;
5941: DMPlexGetCone(dm, f, &cone);
5942: #if defined(PETSC_USE_DEBUG)
5943: 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);
5944: 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);
5945: 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);
5946: 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);
5947: #endif
5948: DMPlexGetConeOrientation(dm, f, &ornt);
5949: /* A face */
5950: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
5951: orntNew[0] = ornt[0];
5952: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax);
5953: orntNew[1] = 0;
5954: coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
5955: orntNew[2] = ornt[1] < 0 ? 0 : -2;
5956: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[2] - eMax);
5957: orntNew[3] = ornt[2] < 0 ? 0 : -2;
5958: DMPlexSetCone(rdm, newp, coneNew);
5959: DMPlexSetConeOrientation(rdm, newp, orntNew);
5960: #if defined(PETSC_USE_DEBUG)
5961: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5962: for (p = 0; p < 4; ++p) {
5963: 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);
5964: }
5965: #endif
5967: /* B face */
5968: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
5969: orntNew[0] = ornt[0];
5970: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[3] - eMax);
5971: orntNew[1] = ornt[3];
5972: coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
5973: orntNew[2] = ornt[1] < 0 ? 0 : -2;
5974: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax);
5975: orntNew[3] = -2;
5976: DMPlexSetCone(rdm, newp+1, coneNew);
5977: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5978: #if defined(PETSC_USE_DEBUG)
5979: 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);
5980: for (p = 0; p < 4; ++p) {
5981: 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);
5982: }
5983: #endif
5985: DMPlexGetSupportSize(dm, f, &size);
5986: DMPlexGetSupport(dm, f, &support);
5987: for (r = 0; r < 2; ++r) {
5988: for (s = 0; s < size; ++s) {
5989: const PetscInt *coneCell, *orntCell, *fornt;
5990: PetscInt coneSize, o, of, c;
5992: DMPlexGetConeSize(dm, support[s], &coneSize);
5993: 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);
5994: DMPlexGetCone(dm, support[s], &coneCell);
5995: DMPlexGetConeOrientation(dm, support[s], &orntCell);
5996: o = orntCell[0] < 0 ? -1 : 1;
5997: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
5998: 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);
5999: if (c == coneSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]);
6000: DMPlexGetConeOrientation(dm, coneCell[0], &fornt);
6001: of = fornt[c-2] < 0 ? -1 : 1;
6002: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3;
6003: }
6004: DMPlexSetSupport(rdm, newp + r, supportRef);
6005: #if defined(PETSC_USE_DEBUG)
6006: for (p = 0; p < size; ++p) {
6007: 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);
6008: }
6009: #endif
6010: }
6011: }
6012: /* Interior hybrid faces have 4 edges and 2 cells */
6013: for (c = cMax; c < cEnd; ++c) {
6014: PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3;
6015: const PetscInt *cone, *ornt;
6016: PetscInt coneNew[4], orntNew[4];
6017: PetscInt supportNew[2];
6019: DMPlexGetCone(dm, c, &cone);
6020: #if defined(PETSC_USE_DEBUG)
6021: 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);
6022: 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);
6023: 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);
6024: 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);
6025: 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);
6026: #endif
6027: DMPlexGetConeOrientation(dm, c, &ornt);
6028: /* Face {a, g, h, d} */
6029: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
6030: orntNew[0] = 0;
6031: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6032: orntNew[1] = 0;
6033: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
6034: orntNew[2] = -2;
6035: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[2] - fMax);
6036: orntNew[3] = -2;
6037: DMPlexSetCone(rdm, newp, coneNew);
6038: DMPlexSetConeOrientation(rdm, newp, orntNew);
6039: #if defined(PETSC_USE_DEBUG)
6040: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6041: for (p = 0; p < 4; ++p) {
6042: 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);
6043: }
6044: #endif
6045: supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0;
6046: supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1;
6047: DMPlexSetSupport(rdm, newp, supportNew);
6048: #if defined(PETSC_USE_DEBUG)
6049: for (p = 0; p < 2; ++p) {
6050: 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);
6051: }
6052: #endif
6053: ++newp;
6054: /* Face {b, g, h, l} */
6055: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
6056: orntNew[0] = 0;
6057: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6058: orntNew[1] = 0;
6059: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
6060: orntNew[2] = -2;
6061: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[3] - fMax);
6062: orntNew[3] = -2;
6063: DMPlexSetCone(rdm, newp, coneNew);
6064: DMPlexSetConeOrientation(rdm, newp, orntNew);
6065: #if defined(PETSC_USE_DEBUG)
6066: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6067: for (p = 0; p < 4; ++p) {
6068: 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);
6069: }
6070: #endif
6071: supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1;
6072: supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2;
6073: DMPlexSetSupport(rdm, newp, supportNew);
6074: #if defined(PETSC_USE_DEBUG)
6075: for (p = 0; p < 2; ++p) {
6076: 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);
6077: }
6078: #endif
6079: ++newp;
6080: /* Face {c, g, h, f} */
6081: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
6082: orntNew[0] = 0;
6083: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6084: orntNew[1] = 0;
6085: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
6086: orntNew[2] = -2;
6087: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[4] - fMax);
6088: orntNew[3] = -2;
6089: DMPlexSetCone(rdm, newp, coneNew);
6090: DMPlexSetConeOrientation(rdm, newp, orntNew);
6091: #if defined(PETSC_USE_DEBUG)
6092: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6093: for (p = 0; p < 4; ++p) {
6094: 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);
6095: }
6096: #endif
6097: supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2;
6098: supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0;
6099: DMPlexSetSupport(rdm, newp, supportNew);
6100: #if defined(PETSC_USE_DEBUG)
6101: for (p = 0; p < 2; ++p) {
6102: 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);
6103: }
6104: #endif
6105: }
6106: /* Face edges have 2 vertices and 2 + cell faces supports */
6107: for (f = fStart; f < fMax; ++f) {
6108: const PetscInt *cone, *ornt, *support;
6109: PetscInt coneSize, supportSize, s;
6111: DMPlexGetSupportSize(dm, f, &supportSize);
6112: DMPlexGetSupport(dm, f, &support);
6113: for (r = 0; r < 3; ++r) {
6114: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
6115: PetscInt coneNew[2];
6116: PetscInt fint[4][3] = { {0, 1, 2},
6117: {3, 4, 0},
6118: {2, 5, 3},
6119: {1, 4, 5} };
6121: DMPlexGetCone(dm, f, &cone);
6122: 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);
6123: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
6124: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart;
6125: DMPlexSetCone(rdm, newp, coneNew);
6126: #if defined(PETSC_USE_DEBUG)
6127: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6128: for (p = 0; p < 2; ++p) {
6129: 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);
6130: }
6131: #endif
6132: supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3;
6133: supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3;
6134: for (s = 0; s < supportSize; ++s) {
6135: PetscInt er;
6137: supportRef[2+s] = -1;
6138: DMPlexGetConeSize(dm, support[s], &coneSize);
6139: 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);
6140: 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);
6141: DMPlexGetCone(dm, support[s], &cone);
6142: DMPlexGetConeOrientation(dm, support[s], &ornt);
6143: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
6144: er = GetTriInteriorEdgeInverse_Static(ornt[c], r);
6145: if (coneSize == 4) {
6146: supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (support[s] - cStart)*6 + fint[c][er];
6147: } else if (coneSize == 5) {
6148: 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);
6149: supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + er;
6150: }
6151: }
6152: DMPlexSetSupport(rdm, newp, supportRef);
6153: #if defined(PETSC_USE_DEBUG)
6154: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6155: for (p = 0; p < supportSize + 2; ++p) {
6156: 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);
6157: }
6158: #endif
6159: }
6160: }
6161: /* Interior cell edges have 2 vertices and 3 faces */
6162: for (c = cStart; c < cMax; ++c) {
6163: const PetscInt *cone;
6164: PetscInt fint[4][3] = { {0,1,2},
6165: {0,3,4},
6166: {2,3,5},
6167: {1,4,5} } ;
6169: DMPlexGetCone(dm, c, &cone);
6170: for (r = 0; r < 4; r++) {
6171: PetscInt coneNew[2], supportNew[3];
6172: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r;
6174: 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);
6175: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
6176: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax -fStart) + c - cStart;
6177: DMPlexSetCone(rdm, newp, coneNew);
6178: #if defined(PETSC_USE_DEBUG)
6179: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6180: for (p = 0; p < 2; ++p) {
6181: 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);
6182: }
6183: #endif
6184: supportNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][0];
6185: supportNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][1];
6186: supportNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][2];
6187: DMPlexSetSupport(rdm, newp, supportNew);
6188: #if defined(PETSC_USE_DEBUG)
6189: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6190: for (p = 0; p < 3; ++p) {
6191: 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);
6192: }
6193: #endif
6194: }
6195: }
6196: /* Hybrid edges have two vertices and the same faces */
6197: for (e = eMax; e < eEnd; ++e) {
6198: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax);
6199: const PetscInt *cone, *support, *fcone;
6200: PetscInt coneNew[2], size, fsize, s;
6202: DMPlexGetCone(dm, e, &cone);
6203: DMPlexGetSupportSize(dm, e, &size);
6204: DMPlexGetSupport(dm, e, &support);
6205: coneNew[0] = vStartNew + (cone[0] - vStart);
6206: coneNew[1] = vStartNew + (cone[1] - vStart);
6207: DMPlexSetCone(rdm, newp, coneNew);
6208: #if defined(PETSC_USE_DEBUG)
6209: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is a edge [%D, %D)", newp, eStartNew, eEndNew);
6210: for (p = 0; p < 2; ++p) {
6211: 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);
6212: }
6213: #endif
6214: for (s = 0; s < size; ++s) {
6215: DMPlexGetConeSize(dm, support[s], &fsize);
6216: DMPlexGetCone(dm, support[s], &fcone);
6217: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
6218: if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]);
6219: supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + c-2;
6220: }
6221: DMPlexSetSupport(rdm, newp, supportRef);
6222: #if defined(PETSC_USE_DEBUG)
6223: for (p = 0; p < size; ++p) {
6224: 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);
6225: }
6226: #endif
6227: }
6228: /* Hybrid face edges have 2 vertices and 2 + cell faces supports */
6229: for (f = fMax; f < fEnd; ++f) {
6230: const PetscInt *cone, *ornt, *support;
6231: PetscInt coneSize, supportSize;
6232: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + f - fMax;
6233: PetscInt coneNew[2], s;
6235: DMPlexGetCone(dm, f, &cone);
6236: #if defined(PETSC_USE_DEBUG)
6237: 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);
6238: 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);
6239: #endif
6240: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
6241: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
6242: DMPlexSetCone(rdm, newp, coneNew);
6243: #if defined(PETSC_USE_DEBUG)
6244: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6245: for (p = 0; p < 2; ++p) {
6246: 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);
6247: }
6248: #endif
6249: supportRef[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 0;
6250: supportRef[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 1;
6251: DMPlexGetSupportSize(dm, f, &supportSize);
6252: DMPlexGetSupport(dm, f, &support);
6253: for (s = 0; s < supportSize; ++s) {
6254: DMPlexGetConeSize(dm, support[s], &coneSize);
6255: 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);
6256: DMPlexGetCone(dm, support[s], &cone);
6257: DMPlexGetConeOrientation(dm, support[s], &ornt);
6258: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
6259: 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);
6260: supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c - 2;
6261: }
6262: DMPlexSetSupport(rdm, newp, supportRef);
6263: #if defined(PETSC_USE_DEBUG)
6264: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6265: for (p = 0; p < supportSize + 2; ++p) {
6266: 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);
6267: }
6268: #endif
6269: }
6270: /* Hybrid cell edges have 2 vertices and 3 faces */
6271: for (c = cMax; c < cEnd; ++c) {
6272: PetscInt coneNew[2], supportNew[3];
6273: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6274: const PetscInt *cone;
6276: DMPlexGetCone(dm, c, &cone);
6277: #if defined(PETSC_USE_DEBUG)
6278: 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);
6279: 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);
6280: #endif
6281: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
6282: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
6283: DMPlexSetCone(rdm, newp, coneNew);
6284: #if defined(PETSC_USE_DEBUG)
6285: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6286: for (p = 0; p < 2; ++p) {
6287: 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);
6288: }
6289: #endif
6290: supportNew[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
6291: supportNew[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
6292: supportNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
6293: DMPlexSetSupport(rdm, newp, supportNew);
6294: #if defined(PETSC_USE_DEBUG)
6295: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6296: for (p = 0; p < 3; ++p) {
6297: 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);
6298: }
6299: #endif
6300: }
6301: /* Old vertices have identical supports */
6302: for (v = vStart; v < vEnd; ++v) {
6303: const PetscInt newp = vStartNew + (v - vStart);
6304: const PetscInt *support, *cone;
6305: PetscInt size, s;
6307: DMPlexGetSupportSize(dm, v, &size);
6308: DMPlexGetSupport(dm, v, &support);
6309: for (s = 0; s < size; ++s) {
6310: const PetscInt e = support[s];
6312: supportRef[s] = -1;
6313: if (eStart <= e) {
6314: if (e < eMax) {
6315: DMPlexGetCone(dm, e, &cone);
6316: supportRef[s] = eStartNew + (e - eStart)*2 + (cone[1] == v ? 1 : 0);
6317: } else if (e < eEnd) {
6318: supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + e - eMax;
6319: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd);
6320: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd);
6321: }
6322: DMPlexSetSupport(rdm, newp, supportRef);
6323: #if defined(PETSC_USE_DEBUG)
6324: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6325: for (p = 0; p < size; ++p) {
6326: 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);
6327: }
6328: #endif
6329: }
6330: /* Interior edge vertices have 2 + faces supports */
6331: for (e = eStart; e < eMax; ++e) {
6332: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
6333: const PetscInt *cone, *support;
6334: PetscInt size, s;
6336: DMPlexGetSupportSize(dm, e, &size);
6337: DMPlexGetSupport(dm, e, &support);
6338: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
6339: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
6340: for (s = 0; s < size; ++s) {
6341: PetscInt r, coneSize;
6343: supportRef[2+s] = -1;
6344: DMPlexGetConeSize(dm, support[s], &coneSize);
6345: 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);
6346: 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);
6347: DMPlexGetCone(dm, support[s], &cone);
6348: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
6349: if (coneSize == 3) supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + r;
6350: else if (coneSize == 4) {
6351: 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);
6352: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + support[s] - fMax;
6353: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax);
6354: }
6355: DMPlexSetSupport(rdm, newp, supportRef);
6356: #if defined(PETSC_USE_DEBUG)
6357: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6358: for (p = 0; p < 2+size; ++p) {
6359: 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);
6360: }
6361: #endif
6362: }
6363: /* Split Edges have 2 vertices and the same faces as the parent */
6364: for (e = eStart; e < eMax; ++e) {
6365: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
6367: for (r = 0; r < 2; ++r) {
6368: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
6369: const PetscInt *cone, *ornt, *support;
6370: PetscInt coneNew[2], coneSize, c, supportSize, s;
6372: DMPlexGetCone(dm, e, &cone);
6373: coneNew[0] = vStartNew + (cone[0] - vStart);
6374: coneNew[1] = vStartNew + (cone[1] - vStart);
6375: coneNew[(r+1)%2] = newv;
6376: DMPlexSetCone(rdm, newp, coneNew);
6377: #if defined(PETSC_USE_DEBUG)
6378: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6379: for (p = 0; p < 2; ++p) {
6380: 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);
6381: }
6382: #endif
6383: DMPlexGetSupportSize(dm, e, &supportSize);
6384: DMPlexGetSupport(dm, e, &support);
6385: for (s = 0; s < supportSize; ++s) {
6386: DMPlexGetConeSize(dm, support[s], &coneSize);
6387: 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);
6388: 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);
6389: DMPlexGetCone(dm, support[s], &cone);
6390: DMPlexGetConeOrientation(dm, support[s], &ornt);
6391: for (c = 0; c < coneSize; ++c) {
6392: if (cone[c] == e) break;
6393: }
6394: if (coneSize == 3) supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3;
6395: else if (coneSize == 4) {
6396: 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);
6397: supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
6398: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax);
6399: }
6400: DMPlexSetSupport(rdm, newp, supportRef);
6401: #if defined(PETSC_USE_DEBUG)
6402: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6403: for (p = 0; p < supportSize; ++p) {
6404: 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);
6405: }
6406: #endif
6407: }
6408: }
6409: /* Face vertices have 3 + cells supports */
6410: for (f = fStart; f < fMax; ++f) {
6411: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
6412: const PetscInt *cone, *support;
6413: PetscInt size, s;
6415: DMPlexGetSupportSize(dm, f, &size);
6416: DMPlexGetSupport(dm, f, &support);
6417: supportRef[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
6418: supportRef[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
6419: supportRef[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
6420: for (s = 0; s < size; ++s) {
6421: PetscInt r, coneSize;
6423: supportRef[3+s] = -1;
6424: DMPlexGetConeSize(dm, support[s], &coneSize);
6425: 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);
6426: 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);
6427: DMPlexGetCone(dm, support[s], &cone);
6428: for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;}
6429: if (coneSize == 4) supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (support[s] - cStart)*4 + r;
6430: else if (coneSize == 5) {
6431: 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);
6432: supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + support[s] - cMax;
6433: }
6434: }
6435: DMPlexSetSupport(rdm, newp, supportRef);
6436: #if defined(PETSC_USE_DEBUG)
6437: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6438: for (p = 0; p < 3+size; ++p) {
6439: 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);
6440: }
6441: #endif
6442: }
6443: /* Interior cell vertices have 4 supports */
6444: for (c = cStart; c < cMax; ++c) {
6445: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart;
6447: supportRef[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
6448: supportRef[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
6449: supportRef[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
6450: supportRef[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
6451: DMPlexSetSupport(rdm, newp, supportRef);
6452: #if defined(PETSC_USE_DEBUG)
6453: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6454: for (p = 0; p < 4; ++p) {
6455: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew);
6456: }
6457: #endif
6458: }
6459: PetscFree(supportRef);
6460: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
6461: break;
6462: case REFINER_HEX_3D:
6463: /*
6464: Bottom (viewed from top) Top
6465: 1---------2---------2 7---------2---------6
6466: | | | | | |
6467: | B 2 C | | H 2 G |
6468: | | | | | |
6469: 3----3----0----1----1 3----3----0----1----1
6470: | | | | | |
6471: | A 0 D | | E 0 F |
6472: | | | | | |
6473: 0---------0---------3 4---------0---------5
6474: */
6475: /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
6476: for (c = cStart; c < cEnd; ++c) {
6477: const PetscInt newp = (c - cStart)*8;
6478: const PetscInt *cone, *ornt;
6479: PetscInt coneNew[6], orntNew[6];
6481: DMPlexGetCone(dm, c, &cone);
6482: DMPlexGetConeOrientation(dm, c, &ornt);
6483: /* A hex */
6484: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
6485: orntNew[0] = ornt[0];
6486: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */
6487: orntNew[1] = 0;
6488: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
6489: orntNew[2] = ornt[2];
6490: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */
6491: orntNew[3] = 0;
6492: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */
6493: orntNew[4] = 0;
6494: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
6495: orntNew[5] = ornt[5];
6496: DMPlexSetCone(rdm, newp+0, coneNew);
6497: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
6498: #if defined(PETSC_USE_DEBUG)
6499: 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);
6500: for (p = 0; p < 6; ++p) {
6501: 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);
6502: }
6503: #endif
6504: /* B hex */
6505: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
6506: orntNew[0] = ornt[0];
6507: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */
6508: orntNew[1] = 0;
6509: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */
6510: orntNew[2] = -1;
6511: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
6512: orntNew[3] = ornt[3];
6513: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */
6514: orntNew[4] = 0;
6515: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
6516: orntNew[5] = ornt[5];
6517: DMPlexSetCone(rdm, newp+1, coneNew);
6518: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
6519: #if defined(PETSC_USE_DEBUG)
6520: 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);
6521: for (p = 0; p < 6; ++p) {
6522: 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);
6523: }
6524: #endif
6525: /* C hex */
6526: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
6527: orntNew[0] = ornt[0];
6528: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */
6529: orntNew[1] = 0;
6530: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */
6531: orntNew[2] = -1;
6532: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
6533: orntNew[3] = ornt[3];
6534: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
6535: orntNew[4] = ornt[4];
6536: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */
6537: orntNew[5] = -4;
6538: DMPlexSetCone(rdm, newp+2, coneNew);
6539: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
6540: #if defined(PETSC_USE_DEBUG)
6541: 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);
6542: for (p = 0; p < 6; ++p) {
6543: 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);
6544: }
6545: #endif
6546: /* D hex */
6547: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
6548: orntNew[0] = ornt[0];
6549: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */
6550: orntNew[1] = 0;
6551: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
6552: orntNew[2] = ornt[2];
6553: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */
6554: orntNew[3] = 0;
6555: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
6556: orntNew[4] = ornt[4];
6557: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */
6558: orntNew[5] = -4;
6559: DMPlexSetCone(rdm, newp+3, coneNew);
6560: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
6561: #if defined(PETSC_USE_DEBUG)
6562: 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);
6563: for (p = 0; p < 6; ++p) {
6564: 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);
6565: }
6566: #endif
6567: /* E hex */
6568: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */
6569: orntNew[0] = -4;
6570: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
6571: orntNew[1] = ornt[1];
6572: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
6573: orntNew[2] = ornt[2];
6574: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */
6575: orntNew[3] = 0;
6576: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */
6577: orntNew[4] = -1;
6578: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
6579: orntNew[5] = ornt[5];
6580: DMPlexSetCone(rdm, newp+4, coneNew);
6581: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
6582: #if defined(PETSC_USE_DEBUG)
6583: 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);
6584: for (p = 0; p < 6; ++p) {
6585: 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);
6586: }
6587: #endif
6588: /* F hex */
6589: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */
6590: orntNew[0] = -4;
6591: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
6592: orntNew[1] = ornt[1];
6593: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
6594: orntNew[2] = ornt[2];
6595: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */
6596: orntNew[3] = -1;
6597: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
6598: orntNew[4] = ornt[4];
6599: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */
6600: orntNew[5] = 1;
6601: DMPlexSetCone(rdm, newp+5, coneNew);
6602: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
6603: #if defined(PETSC_USE_DEBUG)
6604: 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);
6605: for (p = 0; p < 6; ++p) {
6606: 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);
6607: }
6608: #endif
6609: /* G hex */
6610: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */
6611: orntNew[0] = -4;
6612: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
6613: orntNew[1] = ornt[1];
6614: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */
6615: orntNew[2] = 0;
6616: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
6617: orntNew[3] = ornt[3];
6618: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
6619: orntNew[4] = ornt[4];
6620: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */
6621: orntNew[5] = -3;
6622: DMPlexSetCone(rdm, newp+6, coneNew);
6623: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
6624: #if defined(PETSC_USE_DEBUG)
6625: 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);
6626: for (p = 0; p < 6; ++p) {
6627: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew);
6628: }
6629: #endif
6630: /* H hex */
6631: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */
6632: orntNew[0] = -4;
6633: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
6634: orntNew[1] = ornt[1];
6635: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */
6636: orntNew[2] = -1;
6637: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
6638: orntNew[3] = ornt[3];
6639: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */
6640: orntNew[4] = 3;
6641: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
6642: orntNew[5] = ornt[5];
6643: DMPlexSetCone(rdm, newp+7, coneNew);
6644: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
6645: #if defined(PETSC_USE_DEBUG)
6646: 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);
6647: for (p = 0; p < 6; ++p) {
6648: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew);
6649: }
6650: #endif
6651: }
6652: /* Split faces have 4 edges and the same cells as the parent */
6653: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
6654: PetscMalloc1(4 + maxSupportSize*2, &supportRef);
6655: for (f = fStart; f < fEnd; ++f) {
6656: for (r = 0; r < 4; ++r) {
6657: /* TODO: This can come from GetFaces_Internal() */
6658: 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};
6659: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
6660: const PetscInt *cone, *ornt, *support;
6661: PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s;
6663: DMPlexGetCone(dm, f, &cone);
6664: DMPlexGetConeOrientation(dm, f, &ornt);
6665: coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
6666: orntNew[(r+3)%4] = ornt[(r+3)%4];
6667: coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
6668: orntNew[(r+0)%4] = ornt[r];
6669: coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
6670: orntNew[(r+1)%4] = 0;
6671: coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
6672: orntNew[(r+2)%4] = -2;
6673: DMPlexSetCone(rdm, newp, coneNew);
6674: DMPlexSetConeOrientation(rdm, newp, orntNew);
6675: #if defined(PETSC_USE_DEBUG)
6676: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6677: for (p = 0; p < 4; ++p) {
6678: 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);
6679: }
6680: #endif
6681: DMPlexGetSupportSize(dm, f, &supportSize);
6682: DMPlexGetSupport(dm, f, &support);
6683: for (s = 0; s < supportSize; ++s) {
6684: DMPlexGetConeSize(dm, support[s], &coneSize);
6685: DMPlexGetCone(dm, support[s], &cone);
6686: DMPlexGetConeOrientation(dm, support[s], &ornt);
6687: for (c = 0; c < coneSize; ++c) {
6688: if (cone[c] == f) break;
6689: }
6690: supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
6691: }
6692: DMPlexSetSupport(rdm, newp, supportRef);
6693: #if defined(PETSC_USE_DEBUG)
6694: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6695: for (p = 0; p < supportSize; ++p) {
6696: 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);
6697: }
6698: #endif
6699: }
6700: }
6701: /* Interior faces have 4 edges and 2 cells */
6702: for (c = cStart; c < cEnd; ++c) {
6703: 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};
6704: const PetscInt *cone, *ornt;
6705: PetscInt newp, coneNew[4], orntNew[4], supportNew[2];
6707: DMPlexGetCone(dm, c, &cone);
6708: DMPlexGetConeOrientation(dm, c, &ornt);
6709: /* A-D face */
6710: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
6711: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
6712: orntNew[0] = 0;
6713: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6714: orntNew[1] = 0;
6715: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
6716: orntNew[2] = -2;
6717: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
6718: orntNew[3] = -2;
6719: DMPlexSetCone(rdm, newp, coneNew);
6720: DMPlexSetConeOrientation(rdm, newp, orntNew);
6721: #if defined(PETSC_USE_DEBUG)
6722: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6723: for (p = 0; p < 4; ++p) {
6724: 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);
6725: }
6726: #endif
6727: /* C-D face */
6728: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
6729: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
6730: orntNew[0] = 0;
6731: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6732: orntNew[1] = 0;
6733: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
6734: orntNew[2] = -2;
6735: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
6736: orntNew[3] = -2;
6737: DMPlexSetCone(rdm, newp, coneNew);
6738: DMPlexSetConeOrientation(rdm, newp, orntNew);
6739: #if defined(PETSC_USE_DEBUG)
6740: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6741: for (p = 0; p < 4; ++p) {
6742: 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);
6743: }
6744: #endif
6745: /* B-C face */
6746: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
6747: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
6748: orntNew[0] = -2;
6749: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
6750: orntNew[1] = 0;
6751: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
6752: orntNew[2] = 0;
6753: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6754: orntNew[3] = -2;
6755: DMPlexSetCone(rdm, newp, coneNew);
6756: DMPlexSetConeOrientation(rdm, newp, orntNew);
6757: #if defined(PETSC_USE_DEBUG)
6758: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6759: for (p = 0; p < 4; ++p) {
6760: 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);
6761: }
6762: #endif
6763: /* A-B face */
6764: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
6765: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
6766: orntNew[0] = -2;
6767: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
6768: orntNew[1] = 0;
6769: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
6770: orntNew[2] = 0;
6771: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6772: orntNew[3] = -2;
6773: DMPlexSetCone(rdm, newp, coneNew);
6774: DMPlexSetConeOrientation(rdm, newp, orntNew);
6775: #if defined(PETSC_USE_DEBUG)
6776: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6777: for (p = 0; p < 4; ++p) {
6778: 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);
6779: }
6780: #endif
6781: /* E-F face */
6782: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
6783: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
6784: orntNew[0] = -2;
6785: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
6786: orntNew[1] = -2;
6787: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
6788: orntNew[2] = 0;
6789: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6790: orntNew[3] = 0;
6791: DMPlexSetCone(rdm, newp, coneNew);
6792: DMPlexSetConeOrientation(rdm, newp, orntNew);
6793: #if defined(PETSC_USE_DEBUG)
6794: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6795: for (p = 0; p < 4; ++p) {
6796: 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);
6797: }
6798: #endif
6799: /* F-G face */
6800: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
6801: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
6802: orntNew[0] = -2;
6803: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
6804: orntNew[1] = -2;
6805: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
6806: orntNew[2] = 0;
6807: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6808: orntNew[3] = 0;
6809: DMPlexSetCone(rdm, newp, coneNew);
6810: DMPlexSetConeOrientation(rdm, newp, orntNew);
6811: #if defined(PETSC_USE_DEBUG)
6812: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6813: for (p = 0; p < 4; ++p) {
6814: 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);
6815: }
6816: #endif
6817: /* G-H face */
6818: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
6819: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
6820: orntNew[0] = -2;
6821: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
6822: orntNew[1] = 0;
6823: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6824: orntNew[2] = 0;
6825: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
6826: orntNew[3] = -2;
6827: DMPlexSetCone(rdm, newp, coneNew);
6828: DMPlexSetConeOrientation(rdm, newp, orntNew);
6829: #if defined(PETSC_USE_DEBUG)
6830: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6831: for (p = 0; p < 4; ++p) {
6832: 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);
6833: }
6834: #endif
6835: /* E-H face */
6836: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
6837: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
6838: orntNew[0] = -2;
6839: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
6840: orntNew[1] = -2;
6841: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
6842: orntNew[2] = 0;
6843: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6844: orntNew[3] = 0;
6845: DMPlexSetCone(rdm, newp, coneNew);
6846: DMPlexSetConeOrientation(rdm, newp, orntNew);
6847: #if defined(PETSC_USE_DEBUG)
6848: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6849: for (p = 0; p < 4; ++p) {
6850: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew);
6851: }
6852: #endif
6853: /* A-E face */
6854: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
6855: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
6856: orntNew[0] = 0;
6857: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
6858: orntNew[1] = 0;
6859: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
6860: orntNew[2] = -2;
6861: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
6862: orntNew[3] = -2;
6863: DMPlexSetCone(rdm, newp, coneNew);
6864: DMPlexSetConeOrientation(rdm, newp, orntNew);
6865: #if defined(PETSC_USE_DEBUG)
6866: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6867: for (p = 0; p < 4; ++p) {
6868: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew);
6869: }
6870: #endif
6871: /* D-F face */
6872: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
6873: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
6874: orntNew[0] = -2;
6875: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
6876: orntNew[1] = 0;
6877: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
6878: orntNew[2] = 0;
6879: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
6880: orntNew[3] = -2;
6881: DMPlexSetCone(rdm, newp, coneNew);
6882: DMPlexSetConeOrientation(rdm, newp, orntNew);
6883: #if defined(PETSC_USE_DEBUG)
6884: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6885: for (p = 0; p < 4; ++p) {
6886: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew);
6887: }
6888: #endif
6889: /* C-G face */
6890: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
6891: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
6892: orntNew[0] = -2;
6893: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
6894: orntNew[1] = -2;
6895: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
6896: orntNew[2] = 0;
6897: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
6898: orntNew[3] = 0;
6899: DMPlexSetCone(rdm, newp, coneNew);
6900: DMPlexSetConeOrientation(rdm, newp, orntNew);
6901: #if defined(PETSC_USE_DEBUG)
6902: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6903: for (p = 0; p < 4; ++p) {
6904: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew);
6905: }
6906: #endif
6907: /* B-H face */
6908: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
6909: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
6910: orntNew[0] = 0;
6911: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
6912: orntNew[1] = -2;
6913: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
6914: orntNew[2] = -2;
6915: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
6916: orntNew[3] = 0;
6917: DMPlexSetCone(rdm, newp, coneNew);
6918: DMPlexSetConeOrientation(rdm, newp, orntNew);
6919: #if defined(PETSC_USE_DEBUG)
6920: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6921: for (p = 0; p < 4; ++p) {
6922: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew);
6923: }
6924: #endif
6925: for (r = 0; r < 12; ++r) {
6926: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
6927: supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
6928: supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
6929: DMPlexSetSupport(rdm, newp, supportNew);
6930: #if defined(PETSC_USE_DEBUG)
6931: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6932: for (p = 0; p < 2; ++p) {
6933: 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);
6934: }
6935: #endif
6936: }
6937: }
6938: /* Split edges have 2 vertices and the same faces as the parent */
6939: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
6940: for (e = eStart; e < eEnd; ++e) {
6941: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
6943: for (r = 0; r < 2; ++r) {
6944: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
6945: const PetscInt *cone, *ornt, *support;
6946: PetscInt coneNew[2], coneSize, c, supportSize, s;
6948: DMPlexGetCone(dm, e, &cone);
6949: coneNew[0] = vStartNew + (cone[0] - vStart);
6950: coneNew[1] = vStartNew + (cone[1] - vStart);
6951: coneNew[(r+1)%2] = newv;
6952: DMPlexSetCone(rdm, newp, coneNew);
6953: #if defined(PETSC_USE_DEBUG)
6954: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6955: for (p = 0; p < 2; ++p) {
6956: 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);
6957: }
6958: #endif
6959: DMPlexGetSupportSize(dm, e, &supportSize);
6960: DMPlexGetSupport(dm, e, &support);
6961: for (s = 0; s < supportSize; ++s) {
6962: DMPlexGetConeSize(dm, support[s], &coneSize);
6963: DMPlexGetCone(dm, support[s], &cone);
6964: DMPlexGetConeOrientation(dm, support[s], &ornt);
6965: for (c = 0; c < coneSize; ++c) {
6966: if (cone[c] == e) break;
6967: }
6968: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
6969: }
6970: DMPlexSetSupport(rdm, newp, supportRef);
6971: #if defined(PETSC_USE_DEBUG)
6972: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6973: for (p = 0; p < supportSize; ++p) {
6974: 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);
6975: }
6976: #endif
6977: }
6978: }
6979: /* Face edges have 2 vertices and 2+cells faces */
6980: for (f = fStart; f < fEnd; ++f) {
6981: 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};
6982: const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
6983: const PetscInt *cone, *coneCell, *orntCell, *support;
6984: PetscInt coneNew[2], coneSize, c, supportSize, s;
6986: DMPlexGetCone(dm, f, &cone);
6987: for (r = 0; r < 4; ++r) {
6988: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
6990: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
6991: coneNew[1] = newv;
6992: DMPlexSetCone(rdm, newp, coneNew);
6993: #if defined(PETSC_USE_DEBUG)
6994: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6995: for (p = 0; p < 2; ++p) {
6996: 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);
6997: }
6998: #endif
6999: DMPlexGetSupportSize(dm, f, &supportSize);
7000: DMPlexGetSupport(dm, f, &support);
7001: supportRef[0] = fStartNew + (f - fStart)*4 + r;
7002: supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
7003: for (s = 0; s < supportSize; ++s) {
7004: DMPlexGetConeSize(dm, support[s], &coneSize);
7005: DMPlexGetCone(dm, support[s], &coneCell);
7006: DMPlexGetConeOrientation(dm, support[s], &orntCell);
7007: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
7008: supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
7009: }
7010: DMPlexSetSupport(rdm, newp, supportRef);
7011: #if defined(PETSC_USE_DEBUG)
7012: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7013: for (p = 0; p < 2+supportSize; ++p) {
7014: 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);
7015: }
7016: #endif
7017: }
7018: }
7019: /* Cell edges have 2 vertices and 4 faces */
7020: for (c = cStart; c < cEnd; ++c) {
7021: 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};
7022: const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
7023: const PetscInt *cone;
7024: PetscInt coneNew[2], supportNew[4];
7026: DMPlexGetCone(dm, c, &cone);
7027: for (r = 0; r < 6; ++r) {
7028: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
7030: coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
7031: coneNew[1] = newv;
7032: DMPlexSetCone(rdm, newp, coneNew);
7033: #if defined(PETSC_USE_DEBUG)
7034: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7035: for (p = 0; p < 2; ++p) {
7036: 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);
7037: }
7038: #endif
7039: for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
7040: DMPlexSetSupport(rdm, newp, supportNew);
7041: #if defined(PETSC_USE_DEBUG)
7042: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7043: for (p = 0; p < 4; ++p) {
7044: 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);
7045: }
7046: #endif
7047: }
7048: }
7049: /* Old vertices have identical supports */
7050: for (v = vStart; v < vEnd; ++v) {
7051: const PetscInt newp = vStartNew + (v - vStart);
7052: const PetscInt *support, *cone;
7053: PetscInt size, s;
7055: DMPlexGetSupportSize(dm, v, &size);
7056: DMPlexGetSupport(dm, v, &support);
7057: for (s = 0; s < size; ++s) {
7058: PetscInt r = 0;
7060: DMPlexGetCone(dm, support[s], &cone);
7061: if (cone[1] == v) r = 1;
7062: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
7063: }
7064: DMPlexSetSupport(rdm, newp, supportRef);
7065: #if defined(PETSC_USE_DEBUG)
7066: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
7067: for (p = 0; p < size; ++p) {
7068: 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);
7069: }
7070: #endif
7071: }
7072: /* Edge vertices have 2 + faces supports */
7073: for (e = eStart; e < eEnd; ++e) {
7074: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
7075: const PetscInt *cone, *support;
7076: PetscInt size, s;
7078: DMPlexGetSupportSize(dm, e, &size);
7079: DMPlexGetSupport(dm, e, &support);
7080: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
7081: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
7082: for (s = 0; s < size; ++s) {
7083: PetscInt r;
7085: DMPlexGetCone(dm, support[s], &cone);
7086: for (r = 0; r < 4; ++r) if (cone[r] == e) break;
7087: supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
7088: }
7089: DMPlexSetSupport(rdm, newp, supportRef);
7090: #if defined(PETSC_USE_DEBUG)
7091: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
7092: for (p = 0; p < 2+size; ++p) {
7093: 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);
7094: }
7095: #endif
7096: }
7097: /* Face vertices have 4 + cells supports */
7098: for (f = fStart; f < fEnd; ++f) {
7099: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
7100: const PetscInt *cone, *support;
7101: PetscInt size, s;
7103: DMPlexGetSupportSize(dm, f, &size);
7104: DMPlexGetSupport(dm, f, &support);
7105: for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
7106: for (s = 0; s < size; ++s) {
7107: PetscInt r;
7109: DMPlexGetCone(dm, support[s], &cone);
7110: for (r = 0; r < 6; ++r) if (cone[r] == f) break;
7111: supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
7112: }
7113: DMPlexSetSupport(rdm, newp, supportRef);
7114: #if defined(PETSC_USE_DEBUG)
7115: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
7116: for (p = 0; p < 4+size; ++p) {
7117: 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);
7118: }
7119: #endif
7120: }
7121: /* Cell vertices have 6 supports */
7122: for (c = cStart; c < cEnd; ++c) {
7123: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
7124: PetscInt supportNew[6];
7126: for (r = 0; r < 6; ++r) {
7127: supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
7128: }
7129: DMPlexSetSupport(rdm, newp, supportNew);
7130: }
7131: PetscFree(supportRef);
7132: break;
7133: case REFINER_HYBRID_HEX_3D:
7134: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);
7135: /*
7136: Bottom (viewed from top) Top
7137: 1---------2---------2 7---------2---------6
7138: | | | | | |
7139: | B 2 C | | H 2 G |
7140: | | | | | |
7141: 3----3----0----1----1 3----3----0----1----1
7142: | | | | | |
7143: | A 0 D | | E 0 F |
7144: | | | | | |
7145: 0---------0---------3 4---------0---------5
7146: */
7147: /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
7148: for (c = cStart; c < cMax; ++c) {
7149: const PetscInt newp = (c - cStart)*8;
7150: const PetscInt *cone, *ornt;
7151: PetscInt coneNew[6], orntNew[6];
7153: DMPlexGetCone(dm, c, &cone);
7154: DMPlexGetConeOrientation(dm, c, &ornt);
7155: /* A hex */
7156: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
7157: orntNew[0] = ornt[0];
7158: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */
7159: orntNew[1] = 0;
7160: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
7161: orntNew[2] = ornt[2];
7162: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */
7163: orntNew[3] = 0;
7164: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */
7165: orntNew[4] = 0;
7166: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
7167: orntNew[5] = ornt[5];
7168: DMPlexSetCone(rdm, newp+0, coneNew);
7169: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
7170: #if defined(PETSC_USE_DEBUG)
7171: 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);
7172: for (p = 0; p < 6; ++p) {
7173: 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);
7174: }
7175: #endif
7176: /* B hex */
7177: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
7178: orntNew[0] = ornt[0];
7179: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */
7180: orntNew[1] = 0;
7181: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */
7182: orntNew[2] = -1;
7183: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
7184: orntNew[3] = ornt[3];
7185: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */
7186: orntNew[4] = 0;
7187: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
7188: orntNew[5] = ornt[5];
7189: DMPlexSetCone(rdm, newp+1, coneNew);
7190: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
7191: #if defined(PETSC_USE_DEBUG)
7192: 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);
7193: for (p = 0; p < 6; ++p) {
7194: 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);
7195: }
7196: #endif
7197: /* C hex */
7198: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
7199: orntNew[0] = ornt[0];
7200: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */
7201: orntNew[1] = 0;
7202: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */
7203: orntNew[2] = -1;
7204: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
7205: orntNew[3] = ornt[3];
7206: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
7207: orntNew[4] = ornt[4];
7208: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */
7209: orntNew[5] = -4;
7210: DMPlexSetCone(rdm, newp+2, coneNew);
7211: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
7212: #if defined(PETSC_USE_DEBUG)
7213: 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);
7214: for (p = 0; p < 6; ++p) {
7215: 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);
7216: }
7217: #endif
7218: /* D hex */
7219: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
7220: orntNew[0] = ornt[0];
7221: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */
7222: orntNew[1] = 0;
7223: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
7224: orntNew[2] = ornt[2];
7225: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */
7226: orntNew[3] = 0;
7227: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
7228: orntNew[4] = ornt[4];
7229: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */
7230: orntNew[5] = -4;
7231: DMPlexSetCone(rdm, newp+3, coneNew);
7232: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
7233: #if defined(PETSC_USE_DEBUG)
7234: 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);
7235: for (p = 0; p < 6; ++p) {
7236: 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);
7237: }
7238: #endif
7239: /* E hex */
7240: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */
7241: orntNew[0] = -4;
7242: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
7243: orntNew[1] = ornt[1];
7244: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
7245: orntNew[2] = ornt[2];
7246: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */
7247: orntNew[3] = 0;
7248: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */
7249: orntNew[4] = -1;
7250: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
7251: orntNew[5] = ornt[5];
7252: DMPlexSetCone(rdm, newp+4, coneNew);
7253: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
7254: #if defined(PETSC_USE_DEBUG)
7255: 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);
7256: for (p = 0; p < 6; ++p) {
7257: 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);
7258: }
7259: #endif
7260: /* F hex */
7261: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */
7262: orntNew[0] = -4;
7263: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
7264: orntNew[1] = ornt[1];
7265: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
7266: orntNew[2] = ornt[2];
7267: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */
7268: orntNew[3] = -1;
7269: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
7270: orntNew[4] = ornt[4];
7271: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */
7272: orntNew[5] = 1;
7273: DMPlexSetCone(rdm, newp+5, coneNew);
7274: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
7275: #if defined(PETSC_USE_DEBUG)
7276: 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);
7277: for (p = 0; p < 6; ++p) {
7278: 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);
7279: }
7280: #endif
7281: /* G hex */
7282: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */
7283: orntNew[0] = -4;
7284: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
7285: orntNew[1] = ornt[1];
7286: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */
7287: orntNew[2] = 0;
7288: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
7289: orntNew[3] = ornt[3];
7290: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
7291: orntNew[4] = ornt[4];
7292: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */
7293: orntNew[5] = -3;
7294: DMPlexSetCone(rdm, newp+6, coneNew);
7295: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
7296: #if defined(PETSC_USE_DEBUG)
7297: 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);
7298: for (p = 0; p < 6; ++p) {
7299: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew);
7300: }
7301: #endif
7302: /* H hex */
7303: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */
7304: orntNew[0] = -4;
7305: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
7306: orntNew[1] = ornt[1];
7307: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */
7308: orntNew[2] = -1;
7309: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
7310: orntNew[3] = ornt[3];
7311: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */
7312: orntNew[4] = 3;
7313: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
7314: orntNew[5] = ornt[5];
7315: DMPlexSetCone(rdm, newp+7, coneNew);
7316: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
7317: #if defined(PETSC_USE_DEBUG)
7318: 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);
7319: for (p = 0; p < 6; ++p) {
7320: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew);
7321: }
7322: #endif
7323: }
7324: /* Hybrid cells have 6 faces: Front, Back, Sides */
7325: /*
7326: 3---------2---------2
7327: | | |
7328: | D 2 C |
7329: | | |
7330: 3----3----0----1----1
7331: | | |
7332: | A 0 B |
7333: | | |
7334: 0---------0---------1
7335: */
7336: for (c = cMax; c < cEnd; ++c) {
7337: const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4;
7338: const PetscInt *cone, *ornt, *fornt;
7339: PetscInt coneNew[6], orntNew[6], o, of, i;
7341: DMPlexGetCone(dm, c, &cone);
7342: DMPlexGetConeOrientation(dm, c, &ornt);
7343: DMPlexGetConeOrientation(dm, cone[0], &fornt);
7344: o = ornt[0] < 0 ? -1 : 1;
7345: for (r = 0; r < 4; ++r) {
7346: PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
7347: PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
7348: PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
7349: 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]);
7350: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA;
7351: orntNew[0] = ornt[0];
7352: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA;
7353: orntNew[1] = ornt[0];
7354: of = fornt[edgeA] < 0 ? -1 : 1;
7355: i = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
7356: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
7357: orntNew[i] = ornt[edgeA];
7358: i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
7359: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA;
7360: orntNew[i] = 0;
7361: i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
7362: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB;
7363: orntNew[i] = -2;
7364: of = fornt[edgeB] < 0 ? -1 : 1;
7365: i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
7366: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
7367: orntNew[i] = ornt[edgeB];
7368: DMPlexSetCone(rdm, newp+r, coneNew);
7369: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
7370: #if defined(PETSC_USE_DEBUG)
7371: 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);
7372: for (p = 0; p < 2; ++p) {
7373: 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);
7374: }
7375: for (p = 2; p < 6; ++p) {
7376: 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);
7377: }
7378: #endif
7379: }
7380: }
7381: /* Interior split faces have 4 edges and the same cells as the parent */
7382: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
7383: PetscMalloc1(4 + maxSupportSize*2, &supportRef);
7384: for (f = fStart; f < fMax; ++f) {
7385: for (r = 0; r < 4; ++r) {
7386: /* TODO: This can come from GetFaces_Internal() */
7387: 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};
7388: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
7389: const PetscInt *cone, *ornt, *support;
7390: PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s;
7392: DMPlexGetCone(dm, f, &cone);
7393: DMPlexGetConeOrientation(dm, f, &ornt);
7394: coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
7395: orntNew[(r+3)%4] = ornt[(r+3)%4];
7396: coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
7397: orntNew[(r+0)%4] = ornt[r];
7398: coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
7399: orntNew[(r+1)%4] = 0;
7400: coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
7401: orntNew[(r+2)%4] = -2;
7402: DMPlexSetCone(rdm, newp, coneNew);
7403: DMPlexSetConeOrientation(rdm, newp, orntNew);
7404: #if defined(PETSC_USE_DEBUG)
7405: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7406: for (p = 0; p < 4; ++p) {
7407: 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);
7408: }
7409: #endif
7410: DMPlexGetSupportSize(dm, f, &supportSize);
7411: DMPlexGetSupport(dm, f, &support);
7412: for (s = 0; s < supportSize; ++s) {
7413: PetscInt subf;
7414: DMPlexGetConeSize(dm, support[s], &coneSize);
7415: DMPlexGetCone(dm, support[s], &cone);
7416: DMPlexGetConeOrientation(dm, support[s], &ornt);
7417: for (c = 0; c < coneSize; ++c) {
7418: if (cone[c] == f) break;
7419: }
7420: subf = GetQuadSubfaceInverse_Static(ornt[c], r);
7421: if (support[s] < cMax) {
7422: supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
7423: } else {
7424: supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf;
7425: }
7426: }
7427: DMPlexSetSupport(rdm, newp, supportRef);
7428: #if defined(PETSC_USE_DEBUG)
7429: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7430: for (p = 0; p < supportSize; ++p) {
7431: 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);
7432: }
7433: #endif
7434: }
7435: }
7436: /* Interior cell faces have 4 edges and 2 cells */
7437: for (c = cStart; c < cMax; ++c) {
7438: 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};
7439: const PetscInt *cone, *ornt;
7440: PetscInt newp, coneNew[4], orntNew[4], supportNew[2];
7442: DMPlexGetCone(dm, c, &cone);
7443: DMPlexGetConeOrientation(dm, c, &ornt);
7444: /* A-D face */
7445: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
7446: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
7447: orntNew[0] = 0;
7448: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7449: orntNew[1] = 0;
7450: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7451: orntNew[2] = -2;
7452: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
7453: orntNew[3] = -2;
7454: DMPlexSetCone(rdm, newp, coneNew);
7455: DMPlexSetConeOrientation(rdm, newp, orntNew);
7456: #if defined(PETSC_USE_DEBUG)
7457: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7458: for (p = 0; p < 4; ++p) {
7459: 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);
7460: }
7461: #endif
7462: /* C-D face */
7463: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
7464: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
7465: orntNew[0] = 0;
7466: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7467: orntNew[1] = 0;
7468: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7469: orntNew[2] = -2;
7470: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
7471: orntNew[3] = -2;
7472: DMPlexSetCone(rdm, newp, coneNew);
7473: DMPlexSetConeOrientation(rdm, newp, orntNew);
7474: #if defined(PETSC_USE_DEBUG)
7475: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7476: for (p = 0; p < 4; ++p) {
7477: 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);
7478: }
7479: #endif
7480: /* B-C face */
7481: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
7482: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
7483: orntNew[0] = -2;
7484: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
7485: orntNew[1] = 0;
7486: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7487: orntNew[2] = 0;
7488: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7489: orntNew[3] = -2;
7490: DMPlexSetCone(rdm, newp, coneNew);
7491: DMPlexSetConeOrientation(rdm, newp, orntNew);
7492: #if defined(PETSC_USE_DEBUG)
7493: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7494: for (p = 0; p < 4; ++p) {
7495: 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);
7496: }
7497: #endif
7498: /* A-B face */
7499: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
7500: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
7501: orntNew[0] = -2;
7502: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
7503: orntNew[1] = 0;
7504: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7505: orntNew[2] = 0;
7506: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7507: orntNew[3] = -2;
7508: DMPlexSetCone(rdm, newp, coneNew);
7509: DMPlexSetConeOrientation(rdm, newp, orntNew);
7510: #if defined(PETSC_USE_DEBUG)
7511: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7512: for (p = 0; p < 4; ++p) {
7513: 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);
7514: }
7515: #endif
7516: /* E-F face */
7517: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
7518: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7519: orntNew[0] = -2;
7520: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
7521: orntNew[1] = -2;
7522: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
7523: orntNew[2] = 0;
7524: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7525: orntNew[3] = 0;
7526: DMPlexSetCone(rdm, newp, coneNew);
7527: DMPlexSetConeOrientation(rdm, newp, orntNew);
7528: #if defined(PETSC_USE_DEBUG)
7529: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7530: for (p = 0; p < 4; ++p) {
7531: 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);
7532: }
7533: #endif
7534: /* F-G face */
7535: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
7536: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7537: orntNew[0] = -2;
7538: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
7539: orntNew[1] = -2;
7540: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
7541: orntNew[2] = 0;
7542: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7543: orntNew[3] = 0;
7544: DMPlexSetCone(rdm, newp, coneNew);
7545: DMPlexSetConeOrientation(rdm, newp, orntNew);
7546: #if defined(PETSC_USE_DEBUG)
7547: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7548: for (p = 0; p < 4; ++p) {
7549: 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);
7550: }
7551: #endif
7552: /* G-H face */
7553: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
7554: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
7555: orntNew[0] = -2;
7556: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
7557: orntNew[1] = 0;
7558: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7559: orntNew[2] = 0;
7560: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7561: orntNew[3] = -2;
7562: DMPlexSetCone(rdm, newp, coneNew);
7563: DMPlexSetConeOrientation(rdm, newp, orntNew);
7564: #if defined(PETSC_USE_DEBUG)
7565: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7566: for (p = 0; p < 4; ++p) {
7567: 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);
7568: }
7569: #endif
7570: /* E-H face */
7571: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
7572: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7573: orntNew[0] = -2;
7574: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
7575: orntNew[1] = -2;
7576: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
7577: orntNew[2] = 0;
7578: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7579: orntNew[3] = 0;
7580: DMPlexSetCone(rdm, newp, coneNew);
7581: DMPlexSetConeOrientation(rdm, newp, orntNew);
7582: #if defined(PETSC_USE_DEBUG)
7583: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7584: for (p = 0; p < 4; ++p) {
7585: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew);
7586: }
7587: #endif
7588: /* A-E face */
7589: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
7590: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
7591: orntNew[0] = 0;
7592: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7593: orntNew[1] = 0;
7594: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7595: orntNew[2] = -2;
7596: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
7597: orntNew[3] = -2;
7598: DMPlexSetCone(rdm, newp, coneNew);
7599: DMPlexSetConeOrientation(rdm, newp, orntNew);
7600: #if defined(PETSC_USE_DEBUG)
7601: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7602: for (p = 0; p < 4; ++p) {
7603: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew);
7604: }
7605: #endif
7606: /* D-F face */
7607: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
7608: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
7609: orntNew[0] = -2;
7610: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
7611: orntNew[1] = 0;
7612: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7613: orntNew[2] = 0;
7614: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7615: orntNew[3] = -2;
7616: DMPlexSetCone(rdm, newp, coneNew);
7617: DMPlexSetConeOrientation(rdm, newp, orntNew);
7618: #if defined(PETSC_USE_DEBUG)
7619: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7620: for (p = 0; p < 4; ++p) {
7621: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew);
7622: }
7623: #endif
7624: /* C-G face */
7625: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
7626: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7627: orntNew[0] = -2;
7628: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
7629: orntNew[1] = -2;
7630: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
7631: orntNew[2] = 0;
7632: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7633: orntNew[3] = 0;
7634: DMPlexSetCone(rdm, newp, coneNew);
7635: DMPlexSetConeOrientation(rdm, newp, orntNew);
7636: #if defined(PETSC_USE_DEBUG)
7637: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7638: for (p = 0; p < 4; ++p) {
7639: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew);
7640: }
7641: #endif
7642: /* B-H face */
7643: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
7644: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7645: orntNew[0] = 0;
7646: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7647: orntNew[1] = -2;
7648: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
7649: orntNew[2] = -2;
7650: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
7651: orntNew[3] = 0;
7652: DMPlexSetCone(rdm, newp, coneNew);
7653: DMPlexSetConeOrientation(rdm, newp, orntNew);
7654: #if defined(PETSC_USE_DEBUG)
7655: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7656: for (p = 0; p < 4; ++p) {
7657: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew);
7658: }
7659: #endif
7660: for (r = 0; r < 12; ++r) {
7661: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
7662: supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
7663: supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
7664: DMPlexSetSupport(rdm, newp, supportNew);
7665: #if defined(PETSC_USE_DEBUG)
7666: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7667: for (p = 0; p < 2; ++p) {
7668: 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);
7669: }
7670: #endif
7671: }
7672: }
7673: /* Hybrid split faces have 4 edges and same cells */
7674: for (f = fMax; f < fEnd; ++f) {
7675: const PetscInt *cone, *ornt, *support;
7676: PetscInt coneNew[4], orntNew[4];
7677: PetscInt supportNew[2], size, s, c;
7679: DMPlexGetCone(dm, f, &cone);
7680: DMPlexGetConeOrientation(dm, f, &ornt);
7681: DMPlexGetSupportSize(dm, f, &size);
7682: DMPlexGetSupport(dm, f, &support);
7683: for (r = 0; r < 2; ++r) {
7684: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
7686: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
7687: orntNew[0] = ornt[0];
7688: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
7689: orntNew[1] = ornt[1];
7690: coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
7691: orntNew[2+r] = 0;
7692: coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
7693: orntNew[3-r] = 0;
7694: DMPlexSetCone(rdm, newp, coneNew);
7695: DMPlexSetConeOrientation(rdm, newp, orntNew);
7696: #if defined(PETSC_USE_DEBUG)
7697: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
7698: for (p = 0; p < 2; ++p) {
7699: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew);
7700: }
7701: for (p = 2; p < 4; ++p) {
7702: 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);
7703: }
7704: #endif
7705: for (s = 0; s < size; ++s) {
7706: const PetscInt *coneCell, *orntCell, *fornt;
7707: PetscInt o, of;
7709: DMPlexGetCone(dm, support[s], &coneCell);
7710: DMPlexGetConeOrientation(dm, support[s], &orntCell);
7711: o = orntCell[0] < 0 ? -1 : 1;
7712: for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
7713: if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]);
7714: DMPlexGetConeOrientation(dm, coneCell[0], &fornt);
7715: of = fornt[c-2] < 0 ? -1 : 1;
7716: supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4;
7717: }
7718: DMPlexSetSupport(rdm, newp, supportNew);
7719: #if defined(PETSC_USE_DEBUG)
7720: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
7721: for (p = 0; p < size; ++p) {
7722: 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);
7723: }
7724: #endif
7725: }
7726: }
7727: /* Hybrid cell faces have 4 edges and 2 cells */
7728: for (c = cMax; c < cEnd; ++c) {
7729: PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
7730: const PetscInt *cone, *ornt;
7731: PetscInt coneNew[4], orntNew[4];
7732: PetscInt supportNew[2];
7734: DMPlexGetCone(dm, c, &cone);
7735: DMPlexGetConeOrientation(dm, c, &ornt);
7736: for (r = 0; r < 4; ++r) {
7737: #if 0
7738: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
7739: orntNew[0] = 0;
7740: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
7741: orntNew[1] = 0;
7742: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
7743: orntNew[2] = 0;
7744: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
7745: orntNew[3] = 0;
7746: #else
7747: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
7748: orntNew[0] = 0;
7749: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
7750: orntNew[1] = 0;
7751: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
7752: orntNew[2] = 0;
7753: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
7754: orntNew[3] = 0;
7755: #endif
7756: DMPlexSetCone(rdm, newp+r, coneNew);
7757: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
7758: #if defined(PETSC_USE_DEBUG)
7759: 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);
7760: for (p = 0; p < 2; ++p) {
7761: 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);
7762: }
7763: for (p = 2; p < 4; ++p) {
7764: 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);
7765: }
7766: #endif
7767: supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
7768: supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
7769: DMPlexSetSupport(rdm, newp+r, supportNew);
7770: #if defined(PETSC_USE_DEBUG)
7771: 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);
7772: for (p = 0; p < 2; ++p) {
7773: 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);
7774: }
7775: #endif
7776: }
7777: }
7778: /* Interior split edges have 2 vertices and the same faces as the parent */
7779: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
7780: for (e = eStart; e < eMax; ++e) {
7781: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
7783: for (r = 0; r < 2; ++r) {
7784: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
7785: const PetscInt *cone, *ornt, *support;
7786: PetscInt coneNew[2], coneSize, c, supportSize, s;
7788: DMPlexGetCone(dm, e, &cone);
7789: coneNew[0] = vStartNew + (cone[0] - vStart);
7790: coneNew[1] = vStartNew + (cone[1] - vStart);
7791: coneNew[(r+1)%2] = newv;
7792: DMPlexSetCone(rdm, newp, coneNew);
7793: #if defined(PETSC_USE_DEBUG)
7794: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7795: for (p = 0; p < 2; ++p) {
7796: 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);
7797: }
7798: #endif
7799: DMPlexGetSupportSize(dm, e, &supportSize);
7800: DMPlexGetSupport(dm, e, &support);
7801: for (s = 0; s < supportSize; ++s) {
7802: DMPlexGetConeSize(dm, support[s], &coneSize);
7803: DMPlexGetCone(dm, support[s], &cone);
7804: DMPlexGetConeOrientation(dm, support[s], &ornt);
7805: for (c = 0; c < coneSize; ++c) {
7806: if (cone[c] == e) break;
7807: }
7808: if (support[s] < fMax) {
7809: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
7810: } else {
7811: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
7812: }
7813: }
7814: DMPlexSetSupport(rdm, newp, supportRef);
7815: #if defined(PETSC_USE_DEBUG)
7816: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7817: for (p = 0; p < supportSize; ++p) {
7818: 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);
7819: }
7820: #endif
7821: }
7822: }
7823: /* Interior face edges have 2 vertices and 2+cells faces */
7824: for (f = fStart; f < fMax; ++f) {
7825: 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};
7826: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
7827: const PetscInt *cone, *coneCell, *orntCell, *support;
7828: PetscInt coneNew[2], coneSize, c, supportSize, s;
7830: DMPlexGetCone(dm, f, &cone);
7831: for (r = 0; r < 4; ++r) {
7832: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
7834: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
7835: coneNew[1] = newv;
7836: DMPlexSetCone(rdm, newp, coneNew);
7837: #if defined(PETSC_USE_DEBUG)
7838: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7839: for (p = 0; p < 2; ++p) {
7840: 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);
7841: }
7842: #endif
7843: DMPlexGetSupportSize(dm, f, &supportSize);
7844: DMPlexGetSupport(dm, f, &support);
7845: supportRef[0] = fStartNew + (f - fStart)*4 + r;
7846: supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
7847: for (s = 0; s < supportSize; ++s) {
7848: DMPlexGetConeSize(dm, support[s], &coneSize);
7849: DMPlexGetCone(dm, support[s], &coneCell);
7850: DMPlexGetConeOrientation(dm, support[s], &orntCell);
7851: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
7852: if (support[s] < cMax) {
7853: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
7854: } else {
7855: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
7856: }
7857: }
7858: DMPlexSetSupport(rdm, newp, supportRef);
7859: #if defined(PETSC_USE_DEBUG)
7860: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7861: for (p = 0; p < 2+supportSize; ++p) {
7862: 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);
7863: }
7864: #endif
7865: }
7866: }
7867: /* Interior cell edges have 2 vertices and 4 faces */
7868: for (c = cStart; c < cMax; ++c) {
7869: 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};
7870: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
7871: const PetscInt *cone;
7872: PetscInt coneNew[2], supportNew[4];
7874: DMPlexGetCone(dm, c, &cone);
7875: for (r = 0; r < 6; ++r) {
7876: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
7878: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
7879: coneNew[1] = newv;
7880: DMPlexSetCone(rdm, newp, coneNew);
7881: #if defined(PETSC_USE_DEBUG)
7882: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7883: for (p = 0; p < 2; ++p) {
7884: 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);
7885: }
7886: #endif
7887: for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
7888: DMPlexSetSupport(rdm, newp, supportNew);
7889: #if defined(PETSC_USE_DEBUG)
7890: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7891: for (p = 0; p < 4; ++p) {
7892: 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);
7893: }
7894: #endif
7895: }
7896: }
7897: /* Hybrid edges have two vertices and the same faces */
7898: for (e = eMax; e < eEnd; ++e) {
7899: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
7900: const PetscInt *cone, *support, *fcone;
7901: PetscInt coneNew[2], size, fsize, s;
7903: DMPlexGetCone(dm, e, &cone);
7904: DMPlexGetSupportSize(dm, e, &size);
7905: DMPlexGetSupport(dm, e, &support);
7906: coneNew[0] = vStartNew + (cone[0] - vStart);
7907: coneNew[1] = vStartNew + (cone[1] - vStart);
7908: DMPlexSetCone(rdm, newp, coneNew);
7909: #if defined(PETSC_USE_DEBUG)
7910: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
7911: for (p = 0; p < 2; ++p) {
7912: 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);
7913: }
7914: #endif
7915: for (s = 0; s < size; ++s) {
7916: DMPlexGetConeSize(dm, support[s], &fsize);
7917: DMPlexGetCone(dm, support[s], &fcone);
7918: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
7919: if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]);
7920: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
7921: }
7922: DMPlexSetSupport(rdm, newp, supportRef);
7923: #if defined(PETSC_USE_DEBUG)
7924: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
7925: for (p = 0; p < size; ++p) {
7926: 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);
7927: }
7928: #endif
7929: }
7930: /* Hybrid face edges have 2 vertices and 2+cells faces */
7931: for (f = fMax; f < fEnd; ++f) {
7932: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
7933: const PetscInt *cone, *support, *ccone, *cornt;
7934: PetscInt coneNew[2], size, csize, s;
7936: DMPlexGetCone(dm, f, &cone);
7937: DMPlexGetSupportSize(dm, f, &size);
7938: DMPlexGetSupport(dm, f, &support);
7939: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
7940: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
7941: DMPlexSetCone(rdm, newp, coneNew);
7942: #if defined(PETSC_USE_DEBUG)
7943: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
7944: for (p = 0; p < 2; ++p) {
7945: 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);
7946: }
7947: #endif
7948: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
7949: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
7950: for (s = 0; s < size; ++s) {
7951: DMPlexGetConeSize(dm, support[s], &csize);
7952: DMPlexGetCone(dm, support[s], &ccone);
7953: DMPlexGetConeOrientation(dm, support[s], &cornt);
7954: for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
7955: 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]);
7956: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
7957: }
7958: DMPlexSetSupport(rdm, newp, supportRef);
7959: #if defined(PETSC_USE_DEBUG)
7960: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
7961: for (p = 0; p < 2+size; ++p) {
7962: 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);
7963: }
7964: #endif
7965: }
7966: /* Hybrid cell edges have 2 vertices and 4 faces */
7967: for (c = cMax; c < cEnd; ++c) {
7968: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
7969: const PetscInt *cone, *support;
7970: PetscInt coneNew[2], size;
7972: DMPlexGetCone(dm, c, &cone);
7973: DMPlexGetSupportSize(dm, c, &size);
7974: DMPlexGetSupport(dm, c, &support);
7975: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
7976: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
7977: DMPlexSetCone(rdm, newp, coneNew);
7978: #if defined(PETSC_USE_DEBUG)
7979: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
7980: for (p = 0; p < 2; ++p) {
7981: 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);
7982: }
7983: #endif
7984: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
7985: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
7986: supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
7987: supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
7988: DMPlexSetSupport(rdm, newp, supportRef);
7989: #if defined(PETSC_USE_DEBUG)
7990: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
7991: for (p = 0; p < 4; ++p) {
7992: 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);
7993: }
7994: #endif
7995: }
7996: /* Interior vertices have identical supports */
7997: for (v = vStart; v < vEnd; ++v) {
7998: const PetscInt newp = vStartNew + (v - vStart);
7999: const PetscInt *support, *cone;
8000: PetscInt size, s;
8002: DMPlexGetSupportSize(dm, v, &size);
8003: DMPlexGetSupport(dm, v, &support);
8004: for (s = 0; s < size; ++s) {
8005: PetscInt r = 0;
8007: DMPlexGetCone(dm, support[s], &cone);
8008: if (cone[1] == v) r = 1;
8009: if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
8010: else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
8011: }
8012: DMPlexSetSupport(rdm, newp, supportRef);
8013: #if defined(PETSC_USE_DEBUG)
8014: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
8015: for (p = 0; p < size; ++p) {
8016: 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);
8017: }
8018: #endif
8019: }
8020: /* Interior edge vertices have 2 + faces supports */
8021: for (e = eStart; e < eMax; ++e) {
8022: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
8023: const PetscInt *cone, *support;
8024: PetscInt size, s;
8026: DMPlexGetSupportSize(dm, e, &size);
8027: DMPlexGetSupport(dm, e, &support);
8028: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
8029: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
8030: for (s = 0; s < size; ++s) {
8031: PetscInt r;
8033: DMPlexGetCone(dm, support[s], &cone);
8034: for (r = 0; r < 4; ++r) if (cone[r] == e) break;
8035: if (support[s] < fMax) {
8036: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
8037: } else {
8038: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
8039: }
8040: }
8041: DMPlexSetSupport(rdm, newp, supportRef);
8042: #if defined(PETSC_USE_DEBUG)
8043: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
8044: for (p = 0; p < 2+size; ++p) {
8045: 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);
8046: }
8047: #endif
8048: }
8049: /* Interior face vertices have 4 + cells supports */
8050: for (f = fStart; f < fMax; ++f) {
8051: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
8052: const PetscInt *cone, *support;
8053: PetscInt size, s;
8055: DMPlexGetSupportSize(dm, f, &size);
8056: DMPlexGetSupport(dm, f, &support);
8057: for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
8058: for (s = 0; s < size; ++s) {
8059: PetscInt r;
8061: DMPlexGetCone(dm, support[s], &cone);
8062: for (r = 0; r < 6; ++r) if (cone[r] == f) break;
8063: if (support[s] < cMax) {
8064: supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
8065: } else {
8066: supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
8067: }
8068: }
8069: DMPlexSetSupport(rdm, newp, supportRef);
8070: #if defined(PETSC_USE_DEBUG)
8071: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
8072: for (p = 0; p < 4+size; ++p) {
8073: 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);
8074: }
8075: #endif
8076: }
8077: /* Cell vertices have 6 supports */
8078: for (c = cStart; c < cMax; ++c) {
8079: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
8080: PetscInt supportNew[6];
8082: for (r = 0; r < 6; ++r) {
8083: supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
8084: }
8085: DMPlexSetSupport(rdm, newp, supportNew);
8086: }
8087: PetscFree(supportRef);
8088: break;
8089: default:
8090: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
8091: }
8092: return(0);
8093: }
8095: static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
8096: {
8097: PetscSection coordSection, coordSectionNew;
8098: Vec coordinates, coordinatesNew;
8099: PetscScalar *coords, *coordsNew;
8100: const PetscInt numVertices = depthSize ? depthSize[0] : 0;
8101: PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax;
8102: PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
8103: PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL;
8104: VecType vtype;
8105: PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE;
8106: const PetscReal *maxCell, *L;
8107: const DMBoundaryType *bd;
8108: PetscErrorCode ierr;
8111: DMGetDimension(dm, &dim);
8112: DMPlexGetDepth(dm, &depth);
8113: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
8114: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
8115: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
8116: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
8117: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);
8118: if (cMax < 0) cMax = cEnd;
8119: if (fMax < 0) fMax = fEnd;
8120: if (eMax < 0) eMax = eEnd;
8121: GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);
8122: GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);
8123: DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);
8124: /* Determine if we need to localize coordinates when generating them */
8125: if (isperiodic && !maxCell) {
8126: DMGetCoordinatesLocalized(dm, &localize);
8127: if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized");
8128: }
8129: if (isperiodic) {
8130: PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");
8131: PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);
8132: PetscOptionsEnd();
8133: if (localize) {
8134: DMLocalizeCoordinates(dm);
8135: }
8136: }
8137: DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);
8139: DMGetCoordinateSection(dm, &coordSection);
8140: PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);
8141: PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);
8142: PetscSectionSetNumFields(coordSectionNew, 1);
8143: PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);
8145: if (localize) {
8146: PetscInt p, r, newp, *pi;
8148: /* New coordinates will be already localized on the cell */
8149: PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);
8151: /* We need the parentId to properly localize coordinates */
8152: PetscMalloc1(cEndNew-cStartNew,&pi);
8153: switch (refiner) {
8154: case REFINER_NOOP:
8155: break;
8156: case REFINER_SIMPLEX_1D:
8157: for (p = cStart; p < cEnd; ++p) {
8158: for (r = 0; r < 2; ++r) {
8159: newp = (p - cStart)*2 + r;
8160: pi[newp] = p;
8161: }
8162: }
8163: break;
8164: case REFINER_SIMPLEX_2D:
8165: for (p = cStart; p < cEnd; ++p) {
8166: for (r = 0; r < 4; ++r) {
8167: newp = (p - cStart)*4 + r;
8168: pi[newp] = p;
8169: }
8170: }
8171: break;
8172: case REFINER_HEX_2D:
8173: for (p = cStart; p < cEnd; ++p) {
8174: for (r = 0; r < 4; ++r) {
8175: newp = (p - cStart)*4 + r;
8176: pi[newp] = p;
8177: }
8178: }
8179: break;
8180: case REFINER_SIMPLEX_TO_HEX_2D:
8181: for (p = cStart; p < cEnd; ++p) {
8182: for (r = 0; r < 3; ++r) {
8183: newp = (p - cStart)*3 + r;
8184: pi[newp] = p;
8185: }
8186: }
8187: break;
8188: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
8189: for (p = cStart; p < cMax; ++p) {
8190: for (r = 0; r < 3; ++r) {
8191: newp = (p - cStart)*3 + r;
8192: pi[newp] = p;
8193: }
8194: }
8195: for (p = cMax; p < cEnd; ++p) {
8196: for (r = 0; r < 4; ++r) {
8197: newp = (cMax - cStart)*3 + (p - cMax)*4 + r;
8198: pi[newp] = p;
8199: }
8200: }
8201: /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */
8202: cMax = cEnd;
8203: eMax = eEnd;
8204: break;
8205: case REFINER_HYBRID_SIMPLEX_2D:
8206: for (p = cStart; p < cMax; ++p) {
8207: for (r = 0; r < 4; ++r) {
8208: newp = (p - cStart)*4 + r;
8209: pi[newp] = p;
8210: }
8211: }
8212: for (p = cMax; p < cEnd; ++p) {
8213: for (r = 0; r < 2; ++r) {
8214: newp = (cMax - cStart)*4 + (p - cMax)*2 + r;
8215: pi[newp] = p;
8216: }
8217: }
8218: break;
8219: case REFINER_HYBRID_HEX_2D:
8220: for (p = cStart; p < cMax; ++p) {
8221: for (r = 0; r < 4; ++r) {
8222: newp = (p - cStart)*4 + r;
8223: pi[newp] = p;
8224: }
8225: }
8226: for (p = cMax; p < cEnd; ++p) {
8227: for (r = 0; r < 2; ++r) {
8228: newp = (cMax - cStart)*4 + (p - cMax)*2 + r;
8229: pi[newp] = p;
8230: }
8231: }
8232: break;
8233: case REFINER_SIMPLEX_3D:
8234: for (p = cStart; p < cEnd; ++p) {
8235: for (r = 0; r < 8; ++r) {
8236: newp = (p - cStart)*8 + r;
8237: pi[newp] = p;
8238: }
8239: }
8240: break;
8241: case REFINER_HYBRID_SIMPLEX_3D:
8242: for (p = cStart; p < cMax; ++p) {
8243: for (r = 0; r < 8; ++r) {
8244: newp = (p - cStart)*8 + r;
8245: pi[newp] = p;
8246: }
8247: }
8248: for (p = cMax; p < cEnd; ++p) {
8249: for (r = 0; r < 4; ++r) {
8250: newp = (cMax - cStart)*8 + (p - cMax)*4 + r;
8251: pi[newp] = p;
8252: }
8253: }
8254: break;
8255: case REFINER_SIMPLEX_TO_HEX_3D:
8256: for (p = cStart; p < cEnd; ++p) {
8257: for (r = 0; r < 4; ++r) {
8258: newp = (p - cStart)*4 + r;
8259: pi[newp] = p;
8260: }
8261: }
8262: break;
8263: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
8264: for (p = cStart; p < cMax; ++p) {
8265: for (r = 0; r < 4; ++r) {
8266: newp = (p - cStart)*4 + r;
8267: pi[newp] = p;
8268: }
8269: }
8270: for (p = cMax; p < cEnd; ++p) {
8271: for (r = 0; r < 3; ++r) {
8272: newp = (cMax - cStart)*4 + (p - cMax)*3 + r;
8273: pi[newp] = p;
8274: }
8275: }
8276: break;
8277: case REFINER_HEX_3D:
8278: for (p = cStart; p < cEnd; ++p) {
8279: for (r = 0; r < 8; ++r) {
8280: newp = (p - cStart)*8 + r;
8281: pi[newp] = p;
8282: }
8283: }
8284: break;
8285: case REFINER_HYBRID_HEX_3D:
8286: for (p = cStart; p < cMax; ++p) {
8287: for (r = 0; r < 8; ++r) {
8288: newp = (p - cStart)*8 + r;
8289: pi[newp] = p;
8290: }
8291: }
8292: for (p = cMax; p < cEnd; ++p) {
8293: for (r = 0; r < 4; ++r) {
8294: newp = (cMax - cStart)*8 + (p - cMax)*4 + r;
8295: pi[newp] = p;
8296: }
8297: }
8298: break;
8299: default:
8300: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
8301: }
8302: parentId = pi;
8303: } else {
8304: /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */
8305: if (REFINER_HYBRID_SIMPLEX_TO_HEX_2D == refiner) { cMax = cEnd; eMax = eEnd; }
8306: PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);
8307: }
8309: /* All vertices have the spaceDim coordinates */
8310: if (localize) {
8311: PetscInt c;
8313: for (c = cStartNew; c < cEndNew; ++c) {
8314: PetscInt *cone = NULL;
8315: PetscInt closureSize, coneSize = 0, p, pdof;
8317: PetscSectionGetDof(coordSection, parentId[c], &pdof);
8318: if (pdof) { /* localize on all cells that are refinement of a localized parent cell */
8319: DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8320: for (p = 0; p < closureSize*2; p += 2) {
8321: const PetscInt point = cone[p];
8322: if ((point >= vStartNew) && (point < vEndNew)) coneSize++;
8323: }
8324: DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8325: PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);
8326: PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);
8327: }
8328: }
8329: }
8330: for (v = vStartNew; v < vStartNew+numVertices; ++v) {
8331: PetscSectionSetDof(coordSectionNew, v, spaceDim);
8332: PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);
8333: }
8334: PetscSectionSetUp(coordSectionNew);
8335: DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);
8336: DMGetCoordinatesLocal(dm, &coordinates);
8337: PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);
8338: VecCreate(PETSC_COMM_SELF, &coordinatesNew);
8339: PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");
8340: VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);
8341: VecGetBlockSize(coordinates, &bs);
8342: VecSetBlockSize(coordinatesNew, bs);
8343: VecGetType(coordinates, &vtype);
8344: VecSetType(coordinatesNew, vtype);
8345: VecGetArray(coordinates, &coords);
8346: VecGetArray(coordinatesNew, &coordsNew);
8348: switch (refiner) {
8349: case REFINER_NOOP: break;
8350: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
8351: case REFINER_SIMPLEX_TO_HEX_3D:
8352: case REFINER_HEX_3D:
8353: case REFINER_HYBRID_HEX_3D:
8354: /* Face vertices have the average of corner coordinates */
8355: for (f = fStart; f < fMax; ++f) {
8356: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
8357: PetscInt *cone = NULL;
8358: PetscInt closureSize, coneSize = 0, off[8], offnew, p, d;
8360: DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);
8361: for (p = 0; p < closureSize*2; p += 2) {
8362: const PetscInt point = cone[p];
8363: if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
8364: }
8365: if (localize) {
8366: const PetscInt *support = NULL;
8367: PetscInt *rStar = NULL;
8368: PetscInt supportSize, rStarSize, coff, s, ccoff[8];
8369: PetscBool cellfound = PETSC_FALSE;
8371: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8372: DMPlexGetSupportSize(dm,f,&supportSize);
8373: DMPlexGetSupport(dm,f,&support);
8374: /* Compute average of coordinates for each cell sharing the face */
8375: for (s = 0; s < supportSize; ++s) {
8376: PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 };
8377: PetscInt *cellCone = NULL;
8378: PetscInt cellClosureSize, cellConeSize = 0, cdof;
8379: const PetscInt cell = support[s];
8380: PetscBool copyoff = PETSC_FALSE;
8382: DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8383: for (p = 0; p < cellClosureSize*2; p += 2) {
8384: const PetscInt point = cellCone[p];
8385: if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point;
8386: }
8387: PetscSectionGetDof(coordSection, cell, &cdof);
8388: if (!cdof) { /* the parent cell does not have localized coordinates */
8389: cellfound = PETSC_TRUE;
8390: for (v = 0; v < coneSize; ++v) {
8391: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
8392: for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d];
8393: }
8394: for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
8395: } else {
8396: PetscSectionGetOffset(coordSection, cell, &coff);
8397: for (p = 0; p < coneSize; ++p) {
8398: const PetscInt tv = cone[p];
8399: PetscInt cv, voff;
8400: PetscBool locv = PETSC_TRUE;
8402: for (cv = 0; cv < cellConeSize; ++cv) {
8403: if (cellCone[cv] == tv) {
8404: ccoff[p] = spaceDim*cv + coff;
8405: break;
8406: }
8407: }
8408: if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D",tv);
8410: PetscSectionGetOffset(coordSection, cone[p], &voff);
8411: for (d = 0; d < spaceDim; ++d) {
8412: coordsNewAux[d] += coords[ccoff[p]+d];
8413: if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE;
8414: }
8415: if (locv && !cellfound) {
8416: cellfound = PETSC_TRUE;
8417: copyoff = PETSC_TRUE;
8418: }
8419: }
8420: for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
8422: /* Found a valid face for the "vertex" part of the Section (physical space)
8423: i.e., a face that has at least one corner in the physical space */
8424: if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p];
8425: }
8427: /* Localize new coordinates on each refined cell */
8428: for (v = 0; v < rStarSize*2; v += 2) {
8429: if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) {
8430: PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff;
8431: const PetscInt rcell = rStar[v];
8433: PetscSectionGetDof(coordSectionNew, rcell, &rcdof);
8434: if (!rcdof) continue;
8435: PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);
8436: DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8437: for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
8438: if (rcone[p] == newv) {
8439: for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d];
8440: break;
8441: }
8442: if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
8443: }
8444: DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8445: if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8446: }
8447: }
8448: DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8449: }
8450: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8451: if (!cellfound) {
8452: /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */
8453: needcoords = PETSC_TRUE;
8454: coneSize = 0;
8455: }
8456: } else {
8457: for (v = 0; v < coneSize; ++v) {
8458: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
8459: }
8460: }
8461: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8462: if (coneSize) {
8463: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
8464: for (v = 0; v < coneSize; ++v) {DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);}
8465: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
8466: } else {
8467: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
8468: }
8469: DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);
8470: }
8471: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
8472: case REFINER_SIMPLEX_TO_HEX_2D:
8473: case REFINER_HEX_2D:
8474: case REFINER_HYBRID_HEX_2D:
8475: case REFINER_SIMPLEX_1D:
8476: /* Cell vertices have the average of corner coordinates */
8477: for (c = cStart; c < cMax; ++c) {
8478: const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
8479: PetscInt *cone = NULL;
8480: PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0;
8482: DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);
8483: for (p = 0; p < closureSize*2; p += 2) {
8484: const PetscInt point = cone[p];
8485: if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
8486: }
8487: if (localize) {
8488: PetscSectionGetDof(coordSection, c, &cdof);
8489: }
8490: if (cdof) {
8491: PetscInt coff;
8493: PetscSectionGetOffset(coordSection, c, &coff);
8494: for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff;
8495: } else {
8496: for (v = 0; v < coneSize; ++v) {
8497: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
8498: }
8499: }
8500: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8501: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
8502: for (v = 0; v < coneSize; ++v) {DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);}
8503: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
8504: DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);
8506: /* Localize new coordinates on each refined cell */
8507: if (cdof) {
8508: PetscInt *rStar = NULL, rStarSize;
8510: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8511: for (v = 0; v < rStarSize*2; v += 2) {
8512: if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) {
8513: PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof;
8515: rc = rStar[v];
8516: PetscSectionGetDof(coordSectionNew, rc, &rcdof);
8517: if (!rcdof) continue;
8518: PetscSectionGetOffset(coordSectionNew, rc, &coff);
8519: DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);
8520: for (p = 0, lid = 0; p < closureSize*2; p += 2) {
8521: if (cone[p] == newv) {
8522: for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d];
8523: break;
8524: }
8525: if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++;
8526: }
8527: if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8528: DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);
8529: }
8530: }
8531: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8532: }
8533: }
8534: case REFINER_SIMPLEX_2D:
8535: case REFINER_HYBRID_SIMPLEX_2D:
8536: case REFINER_SIMPLEX_3D:
8537: case REFINER_HYBRID_SIMPLEX_3D:
8538: /* Edge vertices have the average of endpoint coordinates */
8539: for (e = eStart; e < eMax; ++e) {
8540: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
8541: const PetscInt *cone;
8542: PetscInt coneSize, offA, offB, offnew, d;
8544: DMPlexGetConeSize(dm, e, &coneSize);
8545: if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize);
8546: DMPlexGetCone(dm, e, &cone);
8547: if (localize) {
8548: PetscInt coff, toffA = -1, toffB = -1, voffA, voffB;
8549: PetscInt *eStar = NULL, eStarSize;
8550: PetscInt *rStar = NULL, rStarSize;
8551: PetscBool cellfound = PETSC_FALSE;
8553: offA = offB = -1;
8554: PetscSectionGetOffset(coordSection, cone[0], &voffA);
8555: PetscSectionGetOffset(coordSection, cone[1], &voffB);
8556: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);
8557: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8558: for (v = 0; v < eStarSize*2; v += 2) {
8559: if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) {
8560: PetscScalar coordsNewAux[3];
8561: PetscInt *cellCone = NULL;
8562: PetscInt cellClosureSize, s, cv, cdof;
8563: PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE;
8564: const PetscInt cell = eStar[v];
8566: PetscSectionGetDof(coordSection, cell, &cdof);
8567: if (!cdof) {
8568: /* Found a valid edge for the "vertex" part of the Section */
8569: offA = voffA;
8570: offB = voffB;
8571: cellfound = PETSC_TRUE;
8572: } else {
8573: PetscSectionGetOffset(coordSection, cell, &coff);
8574: DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8575: for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) {
8576: const PetscInt point = cellCone[s];
8577: if ((point >= vStart) && (point < vEnd)) {
8578: if (point == cone[0]) toffA = spaceDim*cv + coff;
8579: else if (point == cone[1]) toffB = spaceDim*cv + coff;
8580: cv++;
8581: }
8582: }
8583: DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8584: for (d = 0; d < spaceDim; ++d) {
8585: coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]);
8586: if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE;
8587: if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE;
8588: }
8589: /* Found a valid edge for the "vertex" part of the Section */
8590: if (!cellfound && (locvA || locvB)) {
8591: cellfound = PETSC_TRUE;
8592: offA = toffA;
8593: offB = toffB;
8594: }
8595: }
8597: /* Localize new coordinates on each refined cell */
8598: for (s = 0; s < rStarSize*2; s += 2) {
8599: if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) {
8600: PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof;
8601: const PetscInt rcell = rStar[s];
8603: PetscSectionGetDof(coordSectionNew, rcell, &rcdof);
8604: if (!rcdof) continue;
8605: PetscSectionGetOffset(coordSectionNew, rcell, &coff);
8606: DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8607: for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
8608: if (rcone[p] == newv) {
8609: for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d];
8610: break;
8611: }
8612: if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
8613: }
8614: DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8615: if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8616: }
8617: }
8618: }
8619: }
8620: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);
8621: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8622: if (!cellfound) {
8623: /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */
8624: needcoords = PETSC_TRUE;
8625: }
8626: } else {
8627: PetscSectionGetOffset(coordSection, cone[0], &offA);
8628: PetscSectionGetOffset(coordSection, cone[1], &offB);
8629: }
8630: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8631: if (offA != -1 && offB != -1) {
8632: DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);
8633: for (d = 0; d < spaceDim; ++d) {
8634: coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
8635: }
8636: } else {
8637: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
8638: }
8639: }
8640: /* Old vertices have the same coordinates */
8641: for (v = vStart; v < vEnd; ++v) {
8642: const PetscInt newv = vStartNew + (v - vStart);
8643: PetscInt off, offnew, d;
8645: PetscSectionGetOffset(coordSection, v, &off);
8646: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8647: for (d = 0; d < spaceDim; ++d) {
8648: coordsNew[offnew+d] = coords[off+d];
8649: }
8651: /* Localize new coordinates on each refined cell */
8652: if (localize) {
8653: PetscInt p;
8654: PetscInt *rStar = NULL, rStarSize;
8656: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8657: for (p = 0; p < rStarSize*2; p += 2) {
8658: if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) {
8659: PetscScalar ocoords[3];
8660: PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof;
8662: c = rStar[p];
8663: oc = parentId[c-cStartNew];
8664: PetscSectionGetDof(coordSectionNew, c, &cdof);
8665: if (!cdof) continue;
8666: PetscSectionGetDof(coordSection, oc, &cdof);
8667: if (!cdof) continue;
8668: PetscSectionGetOffset(coordSection, oc, &coff);
8669: DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);
8670: for (s = 0, lid = 0; s < closureSize*2; s += 2) {
8671: if (cone[s] == v) {
8672: for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d];
8673: break;
8674: }
8675: if (cone[s] >= vStart && cone[s] < vEnd) lid++;
8676: }
8677: if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D",v);
8678: DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);
8680: PetscSectionGetOffset(coordSectionNew, c, &coff);
8681: DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8682: for (s = 0, lid = 0; s < closureSize*2; s += 2) {
8683: if (cone[s] == newv) {
8684: for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d];
8685: break;
8686: }
8687: if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++;
8688: }
8689: if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8690: DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8691: }
8692: }
8693: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8694: }
8695: }
8696: break;
8697: default:
8698: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
8699: }
8700: VecRestoreArray(coordinates, &coords);
8701: VecRestoreArray(coordinatesNew, &coordsNew);
8702: DMSetCoordinatesLocal(rdm, coordinatesNew);
8704: /* Final reduction (if needed) if we are localizing */
8705: if (localize) {
8706: PetscBool gred;
8708: MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));
8709: if (gred) {
8710: DM cdm;
8711: Vec aux;
8712: PetscSF sf;
8713: const PetscScalar *lArray;
8714: PetscScalar *gArray;
8715: #if defined(PETSC_USE_COMPLEX)
8716: PetscInt i, ln, gn;
8717: PetscReal *lrArray;
8718: PetscReal *grArray;
8719: #endif
8721: DMGetCoordinateDM(rdm, &cdm);
8722: DMCreateGlobalVector(cdm, &aux);
8723: DMGetDefaultSF(cdm, &sf);
8724: VecGetArrayRead(coordinatesNew, &lArray);
8725: VecSet(aux, PETSC_MIN_REAL);
8726: VecGetArray(aux, &gArray);
8727: #if defined(PETSC_USE_COMPLEX)
8728: VecGetLocalSize(aux, &gn);
8729: VecGetLocalSize(coordinatesNew, &ln);
8730: PetscMalloc2(ln,&lrArray,gn,&grArray);
8731: for (i=0;i<ln;i++) lrArray[i] = PetscRealPart(lArray[i]);
8732: for (i=0;i<gn;i++) grArray[i] = PetscRealPart(gArray[i]);
8733: PetscSFReduceBegin(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);
8734: PetscSFReduceEnd(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);
8735: for (i=0;i<gn;i++) gArray[i] = grArray[i];
8736: PetscFree2(lrArray,grArray);
8737: #else
8738: PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);
8739: PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);
8740: #endif
8741: VecRestoreArrayRead(coordinatesNew, &lArray);
8742: VecRestoreArray(aux, &gArray);
8743: DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);
8744: DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);
8745: VecDestroy(&aux);
8746: }
8747: }
8748: VecDestroy(&coordinatesNew);
8749: PetscSectionDestroy(&coordSectionNew);
8750: PetscFree(parentId);
8751: return(0);
8752: }
8754: /*@
8755: DMPlexCreateProcessSF - Create an SF which just has process connectivity
8757: Collective on DM
8759: Input Parameters:
8760: + dm - The DM
8761: - sfPoint - The PetscSF which encodes point connectivity
8763: Output Parameters:
8764: + processRanks - A list of process neighbors, or NULL
8765: - sfProcess - An SF encoding the process connectivity, or NULL
8767: Level: developer
8769: .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
8770: @*/
8771: PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
8772: {
8773: PetscInt numRoots, numLeaves, l;
8774: const PetscInt *localPoints;
8775: const PetscSFNode *remotePoints;
8776: PetscInt *localPointsNew;
8777: PetscSFNode *remotePointsNew;
8778: PetscInt *ranks, *ranksNew;
8779: PetscMPIInt size;
8780: PetscErrorCode ierr;
8787: MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);
8788: PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);
8789: PetscMalloc1(numLeaves, &ranks);
8790: for (l = 0; l < numLeaves; ++l) {
8791: ranks[l] = remotePoints[l].rank;
8792: }
8793: PetscSortRemoveDupsInt(&numLeaves, ranks);
8794: PetscMalloc1(numLeaves, &ranksNew);
8795: PetscMalloc1(numLeaves, &localPointsNew);
8796: PetscMalloc1(numLeaves, &remotePointsNew);
8797: for (l = 0; l < numLeaves; ++l) {
8798: ranksNew[l] = ranks[l];
8799: localPointsNew[l] = l;
8800: remotePointsNew[l].index = 0;
8801: remotePointsNew[l].rank = ranksNew[l];
8802: }
8803: PetscFree(ranks);
8804: if (processRanks) {ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);}
8805: else {PetscFree(ranksNew);}
8806: if (sfProcess) {
8807: PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);
8808: PetscObjectSetName((PetscObject) *sfProcess, "Process SF");
8809: PetscSFSetFromOptions(*sfProcess);
8810: PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);
8811: }
8812: return(0);
8813: }
8815: static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
8816: {
8817: PetscSF sf, sfNew, sfProcess;
8818: IS processRanks;
8819: MPI_Datatype depthType;
8820: PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m;
8821: const PetscInt *localPoints, *neighbors;
8822: const PetscSFNode *remotePoints;
8823: PetscInt *localPointsNew;
8824: PetscSFNode *remotePointsNew;
8825: PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
8826: PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
8827: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
8828: PetscErrorCode ierr;
8831: DMPlexGetChart(rdm, &pStartNew, &pEndNew);
8832: DMPlexGetDepth(dm, &ldepth);
8833: MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));
8834: if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %D != %D", ldepth, depth);
8835: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
8836: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
8837: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
8838: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
8839: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
8840: cMax = cMax < 0 ? cEnd : cMax;
8841: fMax = fMax < 0 ? fEnd : fMax;
8842: eMax = eMax < 0 ? eEnd : eMax;
8843: if (refiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
8844: DMGetPointSF(dm, &sf);
8845: DMGetPointSF(rdm, &sfNew);
8846: /* Calculate size of new SF */
8847: PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);
8848: if (numRoots < 0) return(0);
8849: for (l = 0; l < numLeaves; ++l) {
8850: const PetscInt p = localPoints[l];
8852: switch (refiner) {
8853: case REFINER_SIMPLEX_1D:
8854: if ((p >= vStart) && (p < vEnd)) {
8855: /* Interior vertices stay the same */
8856: ++numLeavesNew;
8857: } else if ((p >= cStart && p < cMax)) {
8858: /* Interior cells add new cells and interior vertices */
8859: numLeavesNew += 2 + 1;
8860: }
8861: break;
8862: case REFINER_SIMPLEX_2D:
8863: case REFINER_HYBRID_SIMPLEX_2D:
8864: if ((p >= vStart) && (p < vEnd)) {
8865: /* Interior vertices stay the same */
8866: ++numLeavesNew;
8867: } else if ((p >= fStart) && (p < fMax)) {
8868: /* Interior faces add new faces and vertex */
8869: numLeavesNew += 2 + 1;
8870: } else if ((p >= fMax) && (p < fEnd)) {
8871: /* Hybrid faces stay the same */
8872: ++numLeavesNew;
8873: } else if ((p >= cStart) && (p < cMax)) {
8874: /* Interior cells add new cells and interior faces */
8875: numLeavesNew += 4 + 3;
8876: } else if ((p >= cMax) && (p < cEnd)) {
8877: /* Hybrid cells add new cells and hybrid face */
8878: numLeavesNew += 2 + 1;
8879: }
8880: break;
8881: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
8882: case REFINER_SIMPLEX_TO_HEX_2D:
8883: if ((p >= vStart) && (p < vEnd)) {
8884: /* Interior vertices stay the same */
8885: ++numLeavesNew;
8886: } else if ((p >= fStart) && (p < fEnd)) {
8887: /* Interior faces add new faces and vertex */
8888: numLeavesNew += 2 + 1;
8889: } else if ((p >= cStart) && (p < cMax)) {
8890: /* Interior cells add new cells, interior faces, and vertex */
8891: numLeavesNew += 3 + 3 + 1;
8892: } else if ((p >= cMax) && (p < cEnd)) {
8893: /* Hybrid cells add new cells, interior faces, and vertex */
8894: numLeavesNew += 4 + 4 + 1;
8895: }
8896: break;
8897: case REFINER_HEX_2D:
8898: case REFINER_HYBRID_HEX_2D:
8899: if ((p >= vStart) && (p < vEnd)) {
8900: /* Interior vertices stay the same */
8901: ++numLeavesNew;
8902: } else if ((p >= fStart) && (p < fMax)) {
8903: /* Interior faces add new faces and vertex */
8904: numLeavesNew += 2 + 1;
8905: } else if ((p >= fMax) && (p < fEnd)) {
8906: /* Hybrid faces stay the same */
8907: ++numLeavesNew;
8908: } else if ((p >= cStart) && (p < cMax)) {
8909: /* Interior cells add new cells, interior faces, and vertex */
8910: numLeavesNew += 4 + 4 + 1;
8911: } else if ((p >= cMax) && (p < cEnd)) {
8912: /* Hybrid cells add new cells and hybrid face */
8913: numLeavesNew += 2 + 1;
8914: }
8915: break;
8916: case REFINER_SIMPLEX_3D:
8917: case REFINER_HYBRID_SIMPLEX_3D:
8918: if ((p >= vStart) && (p < vEnd)) {
8919: /* Interior vertices stay the same */
8920: ++numLeavesNew;
8921: } else if ((p >= eStart) && (p < eMax)) {
8922: /* Interior edges add new edges and vertex */
8923: numLeavesNew += 2 + 1;
8924: } else if ((p >= eMax) && (p < eEnd)) {
8925: /* Hybrid edges stay the same */
8926: ++numLeavesNew;
8927: } else if ((p >= fStart) && (p < fMax)) {
8928: /* Interior faces add new faces and edges */
8929: numLeavesNew += 4 + 3;
8930: } else if ((p >= fMax) && (p < fEnd)) {
8931: /* Hybrid faces add new faces and edges */
8932: numLeavesNew += 2 + 1;
8933: } else if ((p >= cStart) && (p < cMax)) {
8934: /* Interior cells add new cells, faces, and edges */
8935: numLeavesNew += 8 + 8 + 1;
8936: } else if ((p >= cMax) && (p < cEnd)) {
8937: /* Hybrid cells add new cells and faces */
8938: numLeavesNew += 4 + 3;
8939: }
8940: break;
8941: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
8942: case REFINER_SIMPLEX_TO_HEX_3D:
8943: if ((p >= vStart) && (p < vEnd)) {
8944: /* Interior vertices stay the same */
8945: ++numLeavesNew;
8946: } else if ((p >= eStart) && (p < eMax)) {
8947: /* Interior edges add new edges and vertex */
8948: numLeavesNew += 2 + 1;
8949: } else if ((p >= eMax) && (p < eEnd)) {
8950: /* Hybrid edges stay the same */
8951: ++numLeavesNew;
8952: } else if ((p >= fStart) && (p < fMax)) {
8953: /* Interior faces add new faces, edges and a vertex */
8954: numLeavesNew += 3 + 3 + 1;
8955: } else if ((p >= fMax) && (p < fEnd)) {
8956: /* Hybrid faces add new faces and an edge */
8957: numLeavesNew += 2 + 1;
8958: } else if ((p >= cStart) && (p < cMax)) {
8959: /* Interior cells add new cells, faces, edges and a vertex */
8960: numLeavesNew += 4 + 6 + 4 + 1;
8961: } else if ((p >= cMax) && (p < cEnd)) {
8962: /* Hybrid cells add new cells, faces and an edge */
8963: numLeavesNew += 3 + 3 + 1;
8964: }
8965: break;
8966: case REFINER_HEX_3D:
8967: case REFINER_HYBRID_HEX_3D:
8968: if ((p >= vStart) && (p < vEnd)) {
8969: /* Old vertices stay the same */
8970: ++numLeavesNew;
8971: } else if ((p >= eStart) && (p < eMax)) {
8972: /* Interior edges add new edges, and vertex */
8973: numLeavesNew += 2 + 1;
8974: } else if ((p >= eMax) && (p < eEnd)) {
8975: /* Hybrid edges stay the same */
8976: ++numLeavesNew;
8977: } else if ((p >= fStart) && (p < fMax)) {
8978: /* Interior faces add new faces, edges, and vertex */
8979: numLeavesNew += 4 + 4 + 1;
8980: } else if ((p >= fMax) && (p < fEnd)) {
8981: /* Hybrid faces add new faces and edges */
8982: numLeavesNew += 2 + 1;
8983: } else if ((p >= cStart) && (p < cMax)) {
8984: /* Interior cells add new cells, faces, edges, and vertex */
8985: numLeavesNew += 8 + 12 + 6 + 1;
8986: } else if ((p >= cStart) && (p < cEnd)) {
8987: /* Hybrid cells add new cells, faces, and edges */
8988: numLeavesNew += 4 + 4 + 1;
8989: }
8990: break;
8991: default:
8992: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
8993: }
8994: }
8995: /* Communicate depthSizes for each remote rank */
8996: DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);
8997: ISGetLocalSize(processRanks, &numNeighbors);
8998: PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);
8999: PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);
9000: MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);
9001: MPI_Type_commit(&depthType);
9002: PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);
9003: PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);
9004: for (n = 0; n < numNeighbors; ++n) {
9005: GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);
9006: }
9007: depthSizeOld[depth] = cMax;
9008: depthSizeOld[0] = vMax;
9009: depthSizeOld[depth-1] = fMax;
9010: depthSizeOld[1] = eMax;
9012: PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);
9013: PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);
9015: depthSizeOld[depth] = cEnd - cStart;
9016: depthSizeOld[0] = vEnd - vStart;
9017: depthSizeOld[depth-1] = fEnd - fStart;
9018: depthSizeOld[1] = eEnd - eStart;
9020: PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);
9021: PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);
9022: for (n = 0; n < numNeighbors; ++n) {
9023: GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);
9024: rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth];
9025: 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];
9026: rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1];
9027: }
9028: MPI_Type_free(&depthType);
9029: PetscSFDestroy(&sfProcess);
9030: /* Calculate new point SF */
9031: PetscMalloc1(numLeavesNew, &localPointsNew);
9032: PetscMalloc1(numLeavesNew, &remotePointsNew);
9033: ISGetIndices(processRanks, &neighbors);
9034: for (l = 0, m = 0; l < numLeaves; ++l) {
9035: PetscInt p = localPoints[l];
9036: PetscInt rp = remotePoints[l].index, n;
9037: PetscMPIInt rrank = remotePoints[l].rank;
9039: PetscFindInt(rrank, numNeighbors, neighbors, &n);
9040: if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rrank);
9041: switch (refiner) {
9042: case REFINER_SIMPLEX_1D:
9043: if ((p >= vStart) && (p < vEnd)) {
9044: /* Old vertices stay the same */
9045: localPointsNew[m] = vStartNew + (p - vStart);
9046: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9047: remotePointsNew[m].rank = rrank;
9048: ++m;
9049: } else if ((p >= cStart) && (p < cMax)) {
9050: /* Old interior cells add new cells and vertex */
9051: for (r = 0; r < 2; ++r, ++m) {
9052: localPointsNew[m] = cStartNew + (p - cStart)*2 + r;
9053: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r;
9054: remotePointsNew[m].rank = rrank;
9055: }
9056: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart);
9057: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]);
9058: remotePointsNew[m].rank = rrank;
9059: ++m;
9060: }
9061: break;
9062: case REFINER_SIMPLEX_2D:
9063: case REFINER_HYBRID_SIMPLEX_2D:
9064: if ((p >= vStart) && (p < vEnd)) {
9065: /* Old vertices stay the same */
9066: localPointsNew[m] = vStartNew + (p - vStart);
9067: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9068: remotePointsNew[m].rank = rrank;
9069: ++m;
9070: } else if ((p >= fStart) && (p < fMax)) {
9071: /* Old interior faces add new faces and vertex */
9072: for (r = 0; r < 2; ++r, ++m) {
9073: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
9074: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
9075: remotePointsNew[m].rank = rrank;
9076: }
9077: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
9078: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
9079: remotePointsNew[m].rank = rrank;
9080: ++m;
9081: } else if ((p >= fMax) && (p < fEnd)) {
9082: /* Old hybrid faces stay the same */
9083: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax);
9084: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
9085: remotePointsNew[m].rank = rrank;
9086: ++m;
9087: } else if ((p >= cStart) && (p < cMax)) {
9088: /* Old interior cells add new cells and interior faces */
9089: for (r = 0; r < 4; ++r, ++m) {
9090: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9091: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9092: remotePointsNew[m].rank = rrank;
9093: }
9094: for (r = 0; r < 3; ++r, ++m) {
9095: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r;
9096: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
9097: remotePointsNew[m].rank = rrank;
9098: }
9099: } else if ((p >= cMax) && (p < cEnd)) {
9100: /* Old hybrid cells add new cells and hybrid face */
9101: for (r = 0; r < 2; ++r, ++m) {
9102: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9103: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9104: remotePointsNew[m].rank = rrank;
9105: }
9106: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
9107: 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]);
9108: remotePointsNew[m].rank = rrank;
9109: ++m;
9110: }
9111: break;
9112: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9113: case REFINER_SIMPLEX_TO_HEX_2D:
9114: if ((p >= vStart) && (p < vEnd)) {
9115: /* Old vertices stay the same */
9116: localPointsNew[m] = vStartNew + (p - vStart);
9117: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9118: remotePointsNew[m].rank = rrank;
9119: ++m;
9120: } else if ((p >= fStart) && (p < fEnd)) {
9121: /* Old interior faces add new faces and vertex */
9122: for (r = 0; r < 2; ++r, ++m) {
9123: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
9124: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
9125: remotePointsNew[m].rank = rrank;
9126: }
9127: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
9128: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
9129: remotePointsNew[m].rank = rrank;
9130: ++m;
9131: } else if ((p >= cStart) && (p < cMax)) {
9132: /* Old interior cells add new cells, interior faces, and a vertex */
9133: for (r = 0; r < 3; ++r, ++m) {
9134: localPointsNew[m] = cStartNew + (p - cStart)*3 + r;
9135: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r;
9136: remotePointsNew[m].rank = rrank;
9137: }
9138: for (r = 0; r < 3; ++r, ++m) {
9139: localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9140: remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
9141: remotePointsNew[m].rank = rrank;
9142: }
9143: localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9144: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
9145: remotePointsNew[m].rank = rrank;
9146: ++m;
9147: } else if ((p >= cMax) && (p < cEnd)) {
9148: /* Old interior hybrid cells add new cells, interior faces, and a vertex */
9149: for (r = 0; r < 4; ++r, ++m) {
9150: localPointsNew[m] = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r;
9151: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
9152: remotePointsNew[m].rank = rrank;
9153: }
9154: for (r = 0; r < 4; ++r, ++m) {
9155: localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r;
9156: 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;
9157: remotePointsNew[m].rank = rrank;
9158: }
9159: localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9160: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
9161: remotePointsNew[m].rank = rrank;
9162: ++m;
9163: }
9164: break;
9165: case REFINER_HEX_2D:
9166: case REFINER_HYBRID_HEX_2D:
9167: if ((p >= vStart) && (p < vEnd)) {
9168: /* Old vertices stay the same */
9169: localPointsNew[m] = vStartNew + (p - vStart);
9170: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9171: remotePointsNew[m].rank = rrank;
9172: ++m;
9173: } else if ((p >= fStart) && (p < fMax)) {
9174: /* Old interior faces add new faces and vertex */
9175: for (r = 0; r < 2; ++r, ++m) {
9176: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
9177: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
9178: remotePointsNew[m].rank = rrank;
9179: }
9180: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
9181: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
9182: remotePointsNew[m].rank = rrank;
9183: ++m;
9184: } else if ((p >= fMax) && (p < fEnd)) {
9185: /* Old hybrid faces stay the same */
9186: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax);
9187: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
9188: remotePointsNew[m].rank = rrank;
9189: ++m;
9190: } else if ((p >= cStart) && (p < cMax)) {
9191: /* Old interior cells add new cells, interior faces, and vertex */
9192: for (r = 0; r < 4; ++r, ++m) {
9193: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9194: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9195: remotePointsNew[m].rank = rrank;
9196: }
9197: for (r = 0; r < 4; ++r, ++m) {
9198: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r;
9199: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
9200: remotePointsNew[m].rank = rrank;
9201: }
9202: localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart);
9203: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
9204: remotePointsNew[m].rank = rrank;
9205: ++m;
9206: } else if ((p >= cStart) && (p < cMax)) {
9207: /* Old hybrid cells add new cells and hybrid face */
9208: for (r = 0; r < 2; ++r, ++m) {
9209: localPointsNew[m] = cStartNew + (p - cStart)*4 + r; /* TODO: is this a bug? */
9210: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; /* TODO: is this a bug? */
9211: remotePointsNew[m].rank = rrank;
9212: }
9213: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
9214: 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]);
9215: remotePointsNew[m].rank = rrank;
9216: ++m;
9217: }
9218: break;
9219: case REFINER_SIMPLEX_3D:
9220: case REFINER_HYBRID_SIMPLEX_3D:
9221: if ((p >= vStart) && (p < vEnd)) {
9222: /* Interior vertices stay the same */
9223: localPointsNew[m] = vStartNew + (p - vStart);
9224: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9225: remotePointsNew[m].rank = rrank;
9226: ++m;
9227: } else if ((p >= eStart) && (p < eMax)) {
9228: /* Interior edges add new edges and vertex */
9229: for (r = 0; r < 2; ++r, ++m) {
9230: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
9231: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
9232: remotePointsNew[m].rank = rrank;
9233: }
9234: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
9235: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
9236: remotePointsNew[m].rank = rrank;
9237: ++m;
9238: } else if ((p >= eMax) && (p < eEnd)) {
9239: /* Hybrid edges stay the same */
9240: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
9241: 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]);
9242: remotePointsNew[m].rank = rrank;
9243: ++m;
9244: } else if ((p >= fStart) && (p < fMax)) {
9245: /* Interior faces add new faces and edges */
9246: for (r = 0; r < 4; ++r, ++m) {
9247: localPointsNew[m] = fStartNew + (p - fStart)*4 + r;
9248: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
9249: remotePointsNew[m].rank = rrank;
9250: }
9251: for (r = 0; r < 3; ++r, ++m) {
9252: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
9253: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
9254: remotePointsNew[m].rank = rrank;
9255: }
9256: } else if ((p >= fMax) && (p < fEnd)) {
9257: /* Hybrid faces add new faces and edges */
9258: for (r = 0; r < 2; ++r, ++m) {
9259: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
9260: 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;
9261: remotePointsNew[m].rank = rrank;
9262: }
9263: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax);
9264: 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]);
9265: remotePointsNew[m].rank = rrank;
9266: ++m;
9267: } else if ((p >= cStart) && (p < cMax)) {
9268: /* Interior cells add new cells, faces, and edges */
9269: for (r = 0; r < 8; ++r, ++m) {
9270: localPointsNew[m] = cStartNew + (p - cStart)*8 + r;
9271: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
9272: remotePointsNew[m].rank = rrank;
9273: }
9274: for (r = 0; r < 8; ++r, ++m) {
9275: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
9276: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
9277: remotePointsNew[m].rank = rrank;
9278: }
9279: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0;
9280: 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;
9281: remotePointsNew[m].rank = rrank;
9282: ++m;
9283: } else if ((p >= cMax) && (p < cEnd)) {
9284: /* Hybrid cells add new cells and faces */
9285: for (r = 0; r < 4; ++r, ++m) {
9286: localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
9287: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
9288: remotePointsNew[m].rank = rrank;
9289: }
9290: for (r = 0; r < 3; ++r, ++m) {
9291: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
9292: 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;
9293: remotePointsNew[m].rank = rrank;
9294: }
9295: }
9296: break;
9297: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9298: case REFINER_SIMPLEX_TO_HEX_3D:
9299: if ((p >= vStart) && (p < vEnd)) {
9300: /* Interior vertices stay the same */
9301: localPointsNew[m] = vStartNew + (p - vStart);
9302: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9303: remotePointsNew[m].rank = rrank;
9304: ++m;
9305: } else if ((p >= eStart) && (p < eMax)) {
9306: /* Interior edges add new edges and vertex */
9307: for (r = 0; r < 2; ++r, ++m) {
9308: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
9309: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
9310: remotePointsNew[m].rank = rrank;
9311: }
9312: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
9313: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
9314: remotePointsNew[m].rank = rrank;
9315: ++m;
9316: } else if ((p >= eMax) && (p < eEnd)) {
9317: /* Hybrid edges stay the same */
9318: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (p - eMax);
9319: 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]);
9320: remotePointsNew[m].rank = rrank;
9321: ++m;
9322: } else if ((p >= fStart) && (p < fMax)) {
9323: /* Interior faces add new faces, edges and a vertex */
9324: for (r = 0; r < 3; ++r, ++m) {
9325: localPointsNew[m] = fStartNew + (p - fStart)*3 + r;
9326: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r;
9327: remotePointsNew[m].rank = rrank;
9328: }
9329: for (r = 0; r < 3; ++r, ++m) {
9330: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
9331: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
9332: remotePointsNew[m].rank = rrank;
9333: }
9334: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
9335: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
9336: remotePointsNew[m].rank = rrank;
9337: ++m;
9338: } else if ((p >= fMax) && (p < fEnd)) {
9339: /* Interior hybrid faces add new faces and an edge */
9340: for (r = 0; r < 2; ++r, ++m) {
9341: localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r;
9342: 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;
9343: remotePointsNew[m].rank = rrank;
9344: }
9345: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax);
9346: 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]);
9347: remotePointsNew[m].rank = rrank;
9348: ++m;
9349: } else if ((p >= cStart) && (p < cMax)) {
9350: /* Interior cells add new cells, faces, edges, and a vertex */
9351: for (r = 0; r < 4; ++r, ++m) {
9352: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9353: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9354: remotePointsNew[m].rank = rrank;
9355: }
9356: for (r = 0; r < 6; ++r, ++m) {
9357: localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r;
9358: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*6 + r;
9359: remotePointsNew[m].rank = rrank;
9360: }
9361: for (r = 0; r < 4; ++r, ++m) {
9362: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r;
9363: 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;
9364: remotePointsNew[m].rank = rrank;
9365: }
9366: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
9367: 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]);
9368: remotePointsNew[m].rank = rrank;
9369: ++m;
9370: } else if ((p >= cMax) && (p < cEnd)) {
9371: /* Interior hybrid cells add new cells, faces and an edge */
9372: for (r = 0; r < 3; ++r, ++m) {
9373: localPointsNew[m] = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r;
9374: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r;
9375: remotePointsNew[m].rank = rrank;
9376: }
9377: for (r = 0; r < 3; ++r, ++m) {
9378: localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
9379: 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;
9380: remotePointsNew[m].rank = rrank;
9381: }
9382: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax);
9383: 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]);
9384: remotePointsNew[m].rank = rrank;
9385: ++m;
9386: }
9387: break;
9388: case REFINER_HEX_3D:
9389: case REFINER_HYBRID_HEX_3D:
9390: if ((p >= vStart) && (p < vEnd)) {
9391: /* Interior vertices stay the same */
9392: localPointsNew[m] = vStartNew + (p - vStart);
9393: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9394: remotePointsNew[m].rank = rrank;
9395: ++m;
9396: } else if ((p >= eStart) && (p < eMax)) {
9397: /* Interior edges add new edges and vertex */
9398: for (r = 0; r < 2; ++r, ++m) {
9399: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
9400: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
9401: remotePointsNew[m].rank = rrank;
9402: }
9403: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
9404: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
9405: remotePointsNew[m].rank = rrank;
9406: ++m;
9407: } else if ((p >= eMax) && (p < eEnd)) {
9408: /* Hybrid edges stay the same */
9409: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
9410: 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]);
9411: remotePointsNew[m].rank = rrank;
9412: ++m;
9413: } else if ((p >= fStart) && (p < fMax)) {
9414: /* Interior faces add new faces, edges, and vertex */
9415: for (r = 0; r < 4; ++r, ++m) {
9416: localPointsNew[m] = fStartNew + (p - fStart)*4 + r;
9417: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
9418: remotePointsNew[m].rank = rrank;
9419: }
9420: for (r = 0; r < 4; ++r, ++m) {
9421: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
9422: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
9423: remotePointsNew[m].rank = rrank;
9424: }
9425: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
9426: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
9427: remotePointsNew[m].rank = rrank;
9428: ++m;
9429: } else if ((p >= fMax) && (p < fEnd)) {
9430: /* Hybrid faces add new faces and edges */
9431: for (r = 0; r < 2; ++r, ++m) {
9432: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
9433: 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;
9434: remotePointsNew[m].rank = rrank;
9435: }
9436: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax);
9437: 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]);
9438: remotePointsNew[m].rank = rrank;
9439: ++m;
9440: } else if ((p >= cStart) && (p < cMax)) {
9441: /* Interior cells add new cells, faces, edges, and vertex */
9442: for (r = 0; r < 8; ++r, ++m) {
9443: localPointsNew[m] = cStartNew + (p - cStart)*8 + r;
9444: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
9445: remotePointsNew[m].rank = rrank;
9446: }
9447: for (r = 0; r < 12; ++r, ++m) {
9448: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
9449: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
9450: remotePointsNew[m].rank = rrank;
9451: }
9452: for (r = 0; r < 6; ++r, ++m) {
9453: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
9454: 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;
9455: remotePointsNew[m].rank = rrank;
9456: }
9457: for (r = 0; r < 1; ++r, ++m) {
9458: localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r;
9459: remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r;
9460: remotePointsNew[m].rank = rrank;
9461: }
9462: } else if ((p >= cMax) && (p < cEnd)) {
9463: /* Hybrid cells add new cells, faces, and edges */
9464: for (r = 0; r < 4; ++r, ++m) {
9465: localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
9466: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
9467: remotePointsNew[m].rank = rrank;
9468: }
9469: for (r = 0; r < 4; ++r, ++m) {
9470: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
9471: 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;
9472: remotePointsNew[m].rank = rrank;
9473: }
9474: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax);
9475: 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]);
9476: remotePointsNew[m].rank = rrank;
9477: ++m;
9478: }
9479: break;
9480: default:
9481: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
9482: }
9483: }
9484: if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew);
9485: ISRestoreIndices(processRanks, &neighbors);
9486: ISDestroy(&processRanks);
9487: {
9488: PetscSFNode *rp, *rtmp;
9489: PetscInt *lp, *idx, *ltmp, i;
9491: /* SF needs sorted leaves to correct calculate Gather */
9492: PetscMalloc1(numLeavesNew,&idx);
9493: PetscMalloc1(numLeavesNew, &lp);
9494: PetscMalloc1(numLeavesNew, &rp);
9495: for (i = 0; i < numLeavesNew; ++i) {
9496: 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);
9497: idx[i] = i;
9498: }
9499: PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);
9500: for (i = 0; i < numLeavesNew; ++i) {
9501: lp[i] = localPointsNew[idx[i]];
9502: rp[i] = remotePointsNew[idx[i]];
9503: }
9504: ltmp = localPointsNew;
9505: localPointsNew = lp;
9506: rtmp = remotePointsNew;
9507: remotePointsNew = rp;
9508: PetscFree(idx);
9509: PetscFree(ltmp);
9510: PetscFree(rtmp);
9511: }
9512: PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);
9513: PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);
9514: PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);
9515: return(0);
9516: }
9518: static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
9519: {
9520: PetscInt numLabels, l;
9521: PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
9522: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
9526: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
9527: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
9528: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
9529: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
9530: DMPlexGetDepth(dm, &depth);
9531: if (refiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
9532: DMGetNumLabels(dm, &numLabels);
9533: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
9534: switch (refiner) {
9535: case REFINER_NOOP:
9536: case REFINER_SIMPLEX_1D:
9537: case REFINER_SIMPLEX_2D:
9538: case REFINER_SIMPLEX_TO_HEX_2D:
9539: case REFINER_HEX_2D:
9540: case REFINER_SIMPLEX_3D:
9541: case REFINER_HEX_3D:
9542: case REFINER_SIMPLEX_TO_HEX_3D:
9543: break;
9544: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9545: case REFINER_HYBRID_SIMPLEX_3D:
9546: case REFINER_HYBRID_HEX_3D:
9547: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
9548: case REFINER_HYBRID_SIMPLEX_2D:
9549: case REFINER_HYBRID_HEX_2D:
9550: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
9551: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9552: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
9553: break;
9554: default:
9555: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
9556: }
9557: cMax = cMax < 0 ? cEnd : cMax;
9558: fMax = fMax < 0 ? fEnd : fMax;
9559: eMax = eMax < 0 ? eEnd : eMax;
9560: for (l = 0; l < numLabels; ++l) {
9561: DMLabel label, labelNew;
9562: const char *lname;
9563: PetscBool isDepth;
9564: IS valueIS;
9565: const PetscInt *values;
9566: PetscInt defVal;
9567: PetscInt numValues, val;
9569: DMGetLabelName(dm, l, &lname);
9570: PetscStrcmp(lname, "depth", &isDepth);
9571: if (isDepth) continue;
9572: DMCreateLabel(rdm, lname);
9573: DMGetLabel(dm, lname, &label);
9574: DMGetLabel(rdm, lname, &labelNew);
9575: DMLabelGetDefaultValue(label,&defVal);
9576: DMLabelSetDefaultValue(labelNew,defVal);
9577: DMLabelGetValueIS(label, &valueIS);
9578: ISGetLocalSize(valueIS, &numValues);
9579: ISGetIndices(valueIS, &values);
9580: for (val = 0; val < numValues; ++val) {
9581: IS pointIS;
9582: const PetscInt *points;
9583: PetscInt numPoints, n;
9585: DMLabelGetStratumIS(label, values[val], &pointIS);
9586: ISGetLocalSize(pointIS, &numPoints);
9587: ISGetIndices(pointIS, &points);
9588: /* Ensure refined label is created with same number of strata as
9589: * original (even if no entries here). */
9590: DMLabelAddStratum(labelNew, values[val]);
9591: for (n = 0; n < numPoints; ++n) {
9592: const PetscInt p = points[n];
9593: switch (refiner) {
9594: case REFINER_SIMPLEX_1D:
9595: if ((p >= vStart) && (p < vEnd)) {
9596: /* Old vertices stay the same */
9597: newp = vStartNew + (p - vStart);
9598: DMLabelSetValue(labelNew, newp, values[val]);
9599: } else if ((p >= cStart) && (p < cEnd)) {
9600: /* Old cells add new cells and vertex */
9601: newp = vStartNew + (vEnd - vStart) + (p - cStart);
9602: DMLabelSetValue(labelNew, newp, values[val]);
9603: for (r = 0; r < 2; ++r) {
9604: newp = cStartNew + (p - cStart)*2 + r;
9605: DMLabelSetValue(labelNew, newp, values[val]);
9606: }
9607: }
9608: break;
9609: case REFINER_SIMPLEX_2D:
9610: if ((p >= vStart) && (p < vEnd)) {
9611: /* Old vertices stay the same */
9612: newp = vStartNew + (p - vStart);
9613: DMLabelSetValue(labelNew, newp, values[val]);
9614: } else if ((p >= fStart) && (p < fEnd)) {
9615: /* Old faces add new faces and vertex */
9616: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9617: DMLabelSetValue(labelNew, newp, values[val]);
9618: for (r = 0; r < 2; ++r) {
9619: newp = fStartNew + (p - fStart)*2 + r;
9620: DMLabelSetValue(labelNew, newp, values[val]);
9621: }
9622: } else if ((p >= cStart) && (p < cEnd)) {
9623: /* Old cells add new cells and interior faces */
9624: for (r = 0; r < 4; ++r) {
9625: newp = cStartNew + (p - cStart)*4 + r;
9626: DMLabelSetValue(labelNew, newp, values[val]);
9627: }
9628: for (r = 0; r < 3; ++r) {
9629: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9630: DMLabelSetValue(labelNew, newp, values[val]);
9631: }
9632: }
9633: break;
9634: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9635: case REFINER_SIMPLEX_TO_HEX_2D:
9636: if ((p >= vStart) && (p < vEnd)) {
9637: /* Old vertices stay the same */
9638: newp = vStartNew + (p - vStart);
9639: DMLabelSetValue(labelNew, newp, values[val]);
9640: } else if ((p >= fStart) && (p < fEnd)) {
9641: /* Old faces add new faces and vertex */
9642: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9643: DMLabelSetValue(labelNew, newp, values[val]);
9644: for (r = 0; r < 2; ++r) {
9645: newp = fStartNew + (p - fStart)*2 + r;
9646: DMLabelSetValue(labelNew, newp, values[val]);
9647: }
9648: } else if ((p >= cStart) && (p < cMax)) {
9649: /* Old cells add new cells, interior faces, and a vertex */
9650: for (r = 0; r < 3; ++r) {
9651: newp = cStartNew + (p - cStart)*3 + r;
9652: DMLabelSetValue(labelNew, newp, values[val]);
9653: }
9654: for (r = 0; r < 3; ++r) {
9655: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9656: DMLabelSetValue(labelNew, newp, values[val]);
9657: }
9658: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p;
9659: DMLabelSetValue(labelNew, newp, values[val]);
9660: } else if ((p >= cMax) && (p < cEnd)) {
9661: /* Old hybrid cells add new cells, interior faces, and a vertex */
9662: for (r = 0; r < 4; ++r) {
9663: newp = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r;
9664: DMLabelSetValue(labelNew, newp, values[val]);
9665: }
9666: for (r = 0; r < 4; ++r) {
9667: newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r;
9668: DMLabelSetValue(labelNew, newp, values[val]);
9669: }
9670: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p;
9671: DMLabelSetValue(labelNew, newp, values[val]);
9672: }
9673: break;
9674: case REFINER_HEX_2D:
9675: if ((p >= vStart) && (p < vEnd)) {
9676: /* Old vertices stay the same */
9677: newp = vStartNew + (p - vStart);
9678: DMLabelSetValue(labelNew, newp, values[val]);
9679: } else if ((p >= fStart) && (p < fEnd)) {
9680: /* Old faces add new faces and vertex */
9681: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9682: DMLabelSetValue(labelNew, newp, values[val]);
9683: for (r = 0; r < 2; ++r) {
9684: newp = fStartNew + (p - fStart)*2 + r;
9685: DMLabelSetValue(labelNew, newp, values[val]);
9686: }
9687: } else if ((p >= cStart) && (p < cEnd)) {
9688: /* Old cells add new cells and interior faces and vertex */
9689: for (r = 0; r < 4; ++r) {
9690: newp = cStartNew + (p - cStart)*4 + r;
9691: DMLabelSetValue(labelNew, newp, values[val]);
9692: }
9693: for (r = 0; r < 4; ++r) {
9694: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
9695: DMLabelSetValue(labelNew, newp, values[val]);
9696: }
9697: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9698: DMLabelSetValue(labelNew, newp, values[val]);
9699: }
9700: break;
9701: case REFINER_HYBRID_SIMPLEX_2D:
9702: if ((p >= vStart) && (p < vEnd)) {
9703: /* Old vertices stay the same */
9704: newp = vStartNew + (p - vStart);
9705: DMLabelSetValue(labelNew, newp, values[val]);
9706: } else if ((p >= fStart) && (p < fMax)) {
9707: /* Old interior faces add new faces and vertex */
9708: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9709: DMLabelSetValue(labelNew, newp, values[val]);
9710: for (r = 0; r < 2; ++r) {
9711: newp = fStartNew + (p - fStart)*2 + r;
9712: DMLabelSetValue(labelNew, newp, values[val]);
9713: }
9714: } else if ((p >= fMax) && (p < fEnd)) {
9715: /* Old hybrid faces stay the same */
9716: newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
9717: DMLabelSetValue(labelNew, newp, values[val]);
9718: } else if ((p >= cStart) && (p < cMax)) {
9719: /* Old interior cells add new cells and interior faces */
9720: for (r = 0; r < 4; ++r) {
9721: newp = cStartNew + (p - cStart)*4 + r;
9722: DMLabelSetValue(labelNew, newp, values[val]);
9723: }
9724: for (r = 0; r < 3; ++r) {
9725: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9726: DMLabelSetValue(labelNew, newp, values[val]);
9727: }
9728: } else if ((p >= cMax) && (p < cEnd)) {
9729: /* Old hybrid cells add new cells and hybrid face */
9730: for (r = 0; r < 2; ++r) {
9731: newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
9732: DMLabelSetValue(labelNew, newp, values[val]);
9733: }
9734: newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
9735: DMLabelSetValue(labelNew, newp, values[val]);
9736: }
9737: break;
9738: case REFINER_HYBRID_HEX_2D:
9739: if ((p >= vStart) && (p < vEnd)) {
9740: /* Old vertices stay the same */
9741: newp = vStartNew + (p - vStart);
9742: DMLabelSetValue(labelNew, newp, values[val]);
9743: } else if ((p >= fStart) && (p < fMax)) {
9744: /* Old interior faces add new faces and vertex */
9745: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9746: DMLabelSetValue(labelNew, newp, values[val]);
9747: for (r = 0; r < 2; ++r) {
9748: newp = fStartNew + (p - fStart)*2 + r;
9749: DMLabelSetValue(labelNew, newp, values[val]);
9750: }
9751: } else if ((p >= fMax) && (p < fEnd)) {
9752: /* Old hybrid faces stay the same */
9753: newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
9754: DMLabelSetValue(labelNew, newp, values[val]);
9755: } else if ((p >= cStart) && (p < cMax)) {
9756: /* Old interior cells add new cells, interior faces, and vertex */
9757: for (r = 0; r < 4; ++r) {
9758: newp = cStartNew + (p - cStart)*4 + r;
9759: DMLabelSetValue(labelNew, newp, values[val]);
9760: }
9761: for (r = 0; r < 4; ++r) {
9762: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
9763: DMLabelSetValue(labelNew, newp, values[val]);
9764: }
9765: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9766: DMLabelSetValue(labelNew, newp, values[val]);
9767: } else if ((p >= cMax) && (p < cEnd)) {
9768: /* Old hybrid cells add new cells and hybrid face */
9769: for (r = 0; r < 2; ++r) {
9770: newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
9771: DMLabelSetValue(labelNew, newp, values[val]);
9772: }
9773: newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
9774: DMLabelSetValue(labelNew, newp, values[val]);
9775: }
9776: break;
9777: case REFINER_SIMPLEX_3D:
9778: if ((p >= vStart) && (p < vEnd)) {
9779: /* Old vertices stay the same */
9780: newp = vStartNew + (p - vStart);
9781: DMLabelSetValue(labelNew, newp, values[val]);
9782: } else if ((p >= eStart) && (p < eEnd)) {
9783: /* Old edges add new edges and vertex */
9784: for (r = 0; r < 2; ++r) {
9785: newp = eStartNew + (p - eStart)*2 + r;
9786: DMLabelSetValue(labelNew, newp, values[val]);
9787: }
9788: newp = vStartNew + (vEnd - vStart) + (p - eStart);
9789: DMLabelSetValue(labelNew, newp, values[val]);
9790: } else if ((p >= fStart) && (p < fEnd)) {
9791: /* Old faces add new faces and edges */
9792: for (r = 0; r < 4; ++r) {
9793: newp = fStartNew + (p - fStart)*4 + r;
9794: DMLabelSetValue(labelNew, newp, values[val]);
9795: }
9796: for (r = 0; r < 3; ++r) {
9797: newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
9798: DMLabelSetValue(labelNew, newp, values[val]);
9799: }
9800: } else if ((p >= cStart) && (p < cEnd)) {
9801: /* Old cells add new cells and interior faces and edges */
9802: for (r = 0; r < 8; ++r) {
9803: newp = cStartNew + (p - cStart)*8 + r;
9804: DMLabelSetValue(labelNew, newp, values[val]);
9805: }
9806: for (r = 0; r < 8; ++r) {
9807: newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
9808: DMLabelSetValue(labelNew, newp, values[val]);
9809: }
9810: for (r = 0; r < 1; ++r) {
9811: newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
9812: DMLabelSetValue(labelNew, newp, values[val]);
9813: }
9814: }
9815: break;
9816: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9817: case REFINER_SIMPLEX_TO_HEX_3D:
9818: if ((p >= vStart) && (p < vEnd)) {
9819: /* Old vertices stay the same */
9820: newp = vStartNew + (p - vStart);
9821: DMLabelSetValue(labelNew, newp, values[val]);
9822: } else if ((p >= eStart) && (p < eMax)) {
9823: /* Interior edges add new edges and vertex */
9824: for (r = 0; r < 2; ++r) {
9825: newp = eStartNew + (p - eStart)*2 + r;
9826: DMLabelSetValue(labelNew, newp, values[val]);
9827: }
9828: newp = vStartNew + (vEnd - vStart) + (p - eStart);
9829: DMLabelSetValue(labelNew, newp, values[val]);
9830: } else if ((p >= eMax) && (p < eEnd)) {
9831: /* Hybrid edges stay the same */
9832: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + p - eMax;
9833: DMLabelSetValue(labelNew, newp, values[val]);
9834: } else if ((p >= fStart) && (p < fMax)) {
9835: /* Old faces add new faces, edges and a vertex */
9836: for (r = 0; r < 3; ++r) {
9837: newp = fStartNew + (p - fStart)*3 + r;
9838: DMLabelSetValue(labelNew, newp, values[val]);
9839: }
9840: for (r = 0; r < 3; ++r) {
9841: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
9842: DMLabelSetValue(labelNew, newp, values[val]);
9843: }
9844: } else if ((p >= fMax) && (p < fEnd)) {
9845: /* Old hybrid faces add new faces and an edge */
9846: for (r = 0; r < 2; ++r) {
9847: newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r;
9848: DMLabelSetValue(labelNew, newp, values[val]);
9849: }
9850: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax);
9851: DMLabelSetValue(labelNew, newp, values[val]);
9852: } else if ((p >= cStart) && (p < cMax)) {
9853: /* Old cells add new cells and interior faces and edges and a vertex */
9854: for (r = 0; r < 4; ++r) {
9855: newp = cStartNew + (p - cStart)*4 + r;
9856: DMLabelSetValue(labelNew, newp, values[val]);
9857: }
9858: for (r = 0; r < 6; ++r) {
9859: newp = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r;
9860: DMLabelSetValue(labelNew, newp, values[val]);
9861: }
9862: for (r = 0; r < 4; ++r) {
9863: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r;
9864: DMLabelSetValue(labelNew, newp, values[val]);
9865: }
9866: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + p - cStart;
9867: DMLabelSetValue(labelNew, newp, values[val]);
9868: } else if ((p >= cMax) && (p < cEnd)) {
9869: /* Old hybrid cells add new cells and interior faces and an edge */
9870: for (r = 0; r < 3; ++r) {
9871: newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r;
9872: DMLabelSetValue(labelNew, newp, values[val]);
9873: }
9874: for (r = 0; r < 3; ++r) {
9875: newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
9876: DMLabelSetValue(labelNew, newp, values[val]);
9877: }
9878: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + p - cMax;
9879: DMLabelSetValue(labelNew, newp, values[val]);
9880: }
9881: break;
9882: case REFINER_HYBRID_SIMPLEX_3D:
9883: if ((p >= vStart) && (p < vEnd)) {
9884: /* Interior vertices stay the same */
9885: newp = vStartNew + (p - vStart);
9886: DMLabelSetValue(labelNew, newp, values[val]);
9887: } else if ((p >= eStart) && (p < eMax)) {
9888: /* Interior edges add new edges and vertex */
9889: for (r = 0; r < 2; ++r) {
9890: newp = eStartNew + (p - eStart)*2 + r;
9891: DMLabelSetValue(labelNew, newp, values[val]);
9892: }
9893: newp = vStartNew + (vEnd - vStart) + (p - eStart);
9894: DMLabelSetValue(labelNew, newp, values[val]);
9895: } else if ((p >= eMax) && (p < eEnd)) {
9896: /* Hybrid edges stay the same */
9897: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
9898: DMLabelSetValue(labelNew, newp, values[val]);
9899: } else if ((p >= fStart) && (p < fMax)) {
9900: /* Interior faces add new faces and edges */
9901: for (r = 0; r < 4; ++r) {
9902: newp = fStartNew + (p - fStart)*4 + r;
9903: DMLabelSetValue(labelNew, newp, values[val]);
9904: }
9905: for (r = 0; r < 3; ++r) {
9906: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
9907: DMLabelSetValue(labelNew, newp, values[val]);
9908: }
9909: } else if ((p >= fMax) && (p < fEnd)) {
9910: /* Hybrid faces add new faces and edges */
9911: for (r = 0; r < 2; ++r) {
9912: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
9913: DMLabelSetValue(labelNew, newp, values[val]);
9914: }
9915: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
9916: DMLabelSetValue(labelNew, newp, values[val]);
9917: } else if ((p >= cStart) && (p < cMax)) {
9918: /* Interior cells add new cells, faces, and edges */
9919: for (r = 0; r < 8; ++r) {
9920: newp = cStartNew + (p - cStart)*8 + r;
9921: DMLabelSetValue(labelNew, newp, values[val]);
9922: }
9923: for (r = 0; r < 8; ++r) {
9924: newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
9925: DMLabelSetValue(labelNew, newp, values[val]);
9926: }
9927: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
9928: DMLabelSetValue(labelNew, newp, values[val]);
9929: } else if ((p >= cMax) && (p < cEnd)) {
9930: /* Hybrid cells add new cells and faces */
9931: for (r = 0; r < 4; ++r) {
9932: newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
9933: DMLabelSetValue(labelNew, newp, values[val]);
9934: }
9935: for (r = 0; r < 3; ++r) {
9936: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
9937: DMLabelSetValue(labelNew, newp, values[val]);
9938: }
9939: }
9940: break;
9941: case REFINER_HEX_3D:
9942: if ((p >= vStart) && (p < vEnd)) {
9943: /* Old vertices stay the same */
9944: newp = vStartNew + (p - vStart);
9945: DMLabelSetValue(labelNew, newp, values[val]);
9946: } else if ((p >= eStart) && (p < eEnd)) {
9947: /* Old edges add new edges and vertex */
9948: for (r = 0; r < 2; ++r) {
9949: newp = eStartNew + (p - eStart)*2 + r;
9950: DMLabelSetValue(labelNew, newp, values[val]);
9951: }
9952: newp = vStartNew + (vEnd - vStart) + (p - eStart);
9953: DMLabelSetValue(labelNew, newp, values[val]);
9954: } else if ((p >= fStart) && (p < fEnd)) {
9955: /* Old faces add new faces, edges, and vertex */
9956: for (r = 0; r < 4; ++r) {
9957: newp = fStartNew + (p - fStart)*4 + r;
9958: DMLabelSetValue(labelNew, newp, values[val]);
9959: }
9960: for (r = 0; r < 4; ++r) {
9961: newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
9962: DMLabelSetValue(labelNew, newp, values[val]);
9963: }
9964: newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
9965: DMLabelSetValue(labelNew, newp, values[val]);
9966: } else if ((p >= cStart) && (p < cEnd)) {
9967: /* Old cells add new cells, faces, edges, and vertex */
9968: for (r = 0; r < 8; ++r) {
9969: newp = cStartNew + (p - cStart)*8 + r;
9970: DMLabelSetValue(labelNew, newp, values[val]);
9971: }
9972: for (r = 0; r < 12; ++r) {
9973: newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
9974: DMLabelSetValue(labelNew, newp, values[val]);
9975: }
9976: for (r = 0; r < 6; ++r) {
9977: newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
9978: DMLabelSetValue(labelNew, newp, values[val]);
9979: }
9980: newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
9981: DMLabelSetValue(labelNew, newp, values[val]);
9982: }
9983: break;
9984: case REFINER_HYBRID_HEX_3D:
9985: if ((p >= vStart) && (p < vEnd)) {
9986: /* Interior vertices stay the same */
9987: newp = vStartNew + (p - vStart);
9988: DMLabelSetValue(labelNew, newp, values[val]);
9989: } else if ((p >= eStart) && (p < eMax)) {
9990: /* Interior edges add new edges and vertex */
9991: for (r = 0; r < 2; ++r) {
9992: newp = eStartNew + (p - eStart)*2 + r;
9993: DMLabelSetValue(labelNew, newp, values[val]);
9994: }
9995: newp = vStartNew + (vEnd - vStart) + (p - eStart);
9996: DMLabelSetValue(labelNew, newp, values[val]);
9997: } else if ((p >= eMax) && (p < eEnd)) {
9998: /* Hybrid edges stay the same */
9999: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
10000: DMLabelSetValue(labelNew, newp, values[val]);
10001: } else if ((p >= fStart) && (p < fMax)) {
10002: /* Interior faces add new faces, edges, and vertex */
10003: for (r = 0; r < 4; ++r) {
10004: newp = fStartNew + (p - fStart)*4 + r;
10005: DMLabelSetValue(labelNew, newp, values[val]);
10006: }
10007: for (r = 0; r < 4; ++r) {
10008: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
10009: DMLabelSetValue(labelNew, newp, values[val]);
10010: }
10011: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
10012: DMLabelSetValue(labelNew, newp, values[val]);
10013: } else if ((p >= fMax) && (p < fEnd)) {
10014: /* Hybrid faces add new faces and edges */
10015: for (r = 0; r < 2; ++r) {
10016: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
10017: DMLabelSetValue(labelNew, newp, values[val]);
10018: }
10019: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
10020: DMLabelSetValue(labelNew, newp, values[val]);
10021: } else if ((p >= cStart) && (p < cMax)) {
10022: /* Interior cells add new cells, faces, edges, and vertex */
10023: for (r = 0; r < 8; ++r) {
10024: newp = cStartNew + (p - cStart)*8 + r;
10025: DMLabelSetValue(labelNew, newp, values[val]);
10026: }
10027: for (r = 0; r < 12; ++r) {
10028: newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
10029: DMLabelSetValue(labelNew, newp, values[val]);
10030: }
10031: for (r = 0; r < 6; ++r) {
10032: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
10033: DMLabelSetValue(labelNew, newp, values[val]);
10034: }
10035: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
10036: DMLabelSetValue(labelNew, newp, values[val]);
10037: } else if ((p >= cMax) && (p < cEnd)) {
10038: /* Hybrid cells add new cells, faces, and edges */
10039: for (r = 0; r < 4; ++r) {
10040: newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
10041: DMLabelSetValue(labelNew, newp, values[val]);
10042: }
10043: for (r = 0; r < 4; ++r) {
10044: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
10045: DMLabelSetValue(labelNew, newp, values[val]);
10046: }
10047: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
10048: DMLabelSetValue(labelNew, newp, values[val]);
10049: }
10050: break;
10051: default:
10052: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner);
10053: }
10054: }
10055: ISRestoreIndices(pointIS, &points);
10056: ISDestroy(&pointIS);
10057: }
10058: ISRestoreIndices(valueIS, &values);
10059: ISDestroy(&valueIS);
10060: if (0) {
10061: DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);
10062: }
10063: }
10064: return(0);
10065: }
10067: /* This will only work for interpolated meshes */
10068: PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
10069: {
10070: DM rdm;
10071: PetscInt *depthSize;
10072: PetscInt dim, embedDim, depth = 0, d, pStart = 0, pEnd = 0;
10076: DMCreate(PetscObjectComm((PetscObject)dm), &rdm);
10077: DMSetType(rdm, DMPLEX);
10078: DMGetDimension(dm, &dim);
10079: DMSetDimension(rdm, dim);
10080: DMGetCoordinateDim(dm, &embedDim);
10081: DMSetCoordinateDim(rdm, embedDim);
10082: /* Calculate number of new points of each depth */
10083: DMPlexGetDepth(dm, &depth);
10084: if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
10085: PetscMalloc1(depth+1, &depthSize);
10086: PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));
10087: CellRefinerGetSizes(cellRefiner, dm, depthSize);
10088: /* Step 1: Set chart */
10089: for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
10090: DMPlexSetChart(rdm, pStart, pEnd);
10091: /* Step 2: Set cone/support sizes (automatically stratifies) */
10092: CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);
10093: /* Step 3: Setup refined DM */
10094: DMSetUp(rdm);
10095: /* Step 4: Set cones and supports (automatically symmetrizes) */
10096: CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);
10097: /* Step 5: Create pointSF */
10098: CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);
10099: /* Step 6: Create labels */
10100: CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);
10101: /* Step 7: Set coordinates */
10102: CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);
10103: PetscFree(depthSize);
10105: *dmRefined = rdm;
10106: return(0);
10107: }
10109: /*@
10110: DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
10112: Input Parameter:
10113: . dm - The coarse DM
10115: Output Parameter:
10116: . fpointIS - The IS of all the fine points which exist in the original coarse mesh
10118: Level: developer
10120: .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
10121: @*/
10122: PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
10123: {
10124: CellRefiner cellRefiner;
10125: PetscInt *depthSize, *fpoints;
10126: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
10127: PetscInt depth, pStart, pEnd, p, vStart, vEnd, v;
10131: DMPlexGetDepth(dm, &depth);
10132: DMPlexGetChart(dm, &pStart, &pEnd);
10133: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
10134: DMPlexGetCellRefiner_Internal(dm, &cellRefiner);
10135: PetscMalloc1(depth+1, &depthSize);
10136: CellRefinerGetSizes(cellRefiner, dm, depthSize);
10137: if (cellRefiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
10138: PetscMalloc1(pEnd-pStart,&fpoints);
10139: for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
10140: switch (cellRefiner) {
10141: case REFINER_SIMPLEX_1D:
10142: case REFINER_SIMPLEX_2D:
10143: case REFINER_HYBRID_SIMPLEX_2D:
10144: case REFINER_HEX_2D:
10145: case REFINER_HYBRID_HEX_2D:
10146: case REFINER_SIMPLEX_3D:
10147: case REFINER_HYBRID_SIMPLEX_3D:
10148: case REFINER_HEX_3D:
10149: case REFINER_HYBRID_HEX_3D:
10150: for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
10151: break;
10152: default:
10153: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", cellRefiner);
10154: }
10155: ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);
10156: PetscFree(depthSize);
10157: return(0);
10158: }
10160: /*@
10161: DMPlexSetRefinementUniform - Set the flag for uniform refinement
10163: Input Parameters:
10164: + dm - The DM
10165: - refinementUniform - The flag for uniform refinement
10167: Level: developer
10169: .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10170: @*/
10171: PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
10172: {
10173: DM_Plex *mesh = (DM_Plex*) dm->data;
10177: mesh->refinementUniform = refinementUniform;
10178: return(0);
10179: }
10181: /*@
10182: DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
10184: Input Parameter:
10185: . dm - The DM
10187: Output Parameter:
10188: . refinementUniform - The flag for uniform refinement
10190: Level: developer
10192: .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10193: @*/
10194: PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
10195: {
10196: DM_Plex *mesh = (DM_Plex*) dm->data;
10201: *refinementUniform = mesh->refinementUniform;
10202: return(0);
10203: }
10205: /*@
10206: DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
10208: Input Parameters:
10209: + dm - The DM
10210: - refinementLimit - The maximum cell volume in the refined mesh
10212: Level: developer
10214: .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
10215: @*/
10216: PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
10217: {
10218: DM_Plex *mesh = (DM_Plex*) dm->data;
10222: mesh->refinementLimit = refinementLimit;
10223: return(0);
10224: }
10226: /*@
10227: DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
10229: Input Parameter:
10230: . dm - The DM
10232: Output Parameter:
10233: . refinementLimit - The maximum cell volume in the refined mesh
10235: Level: developer
10237: .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
10238: @*/
10239: PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
10240: {
10241: DM_Plex *mesh = (DM_Plex*) dm->data;
10246: /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
10247: *refinementLimit = mesh->refinementLimit;
10248: return(0);
10249: }
10251: /*@
10252: DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
10254: Input Parameters:
10255: + dm - The DM
10256: - refinementFunc - Function giving the maximum cell volume in the refined mesh
10258: Note: The calling sequence is refinementFunc(coords, limit)
10259: $ coords - Coordinates of the current point, usually a cell centroid
10260: $ limit - The maximum cell volume for a cell containing this point
10262: Level: developer
10264: .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10265: @*/
10266: PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
10267: {
10268: DM_Plex *mesh = (DM_Plex*) dm->data;
10272: mesh->refinementFunc = refinementFunc;
10273: return(0);
10274: }
10276: /*@
10277: DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
10279: Input Parameter:
10280: . dm - The DM
10282: Output Parameter:
10283: . refinementFunc - Function giving the maximum cell volume in the refined mesh
10285: Note: The calling sequence is refinementFunc(coords, limit)
10286: $ coords - Coordinates of the current point, usually a cell centroid
10287: $ limit - The maximum cell volume for a cell containing this point
10289: Level: developer
10291: .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10292: @*/
10293: PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
10294: {
10295: DM_Plex *mesh = (DM_Plex*) dm->data;
10300: *refinementFunc = mesh->refinementFunc;
10301: return(0);
10302: }
10304: PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
10305: {
10306: PetscInt dim, cStart, cEnd, coneSize, cMax, fMax;
10310: DMGetDimension(dm, &dim);
10311: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
10312: if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; return(0);}
10313: DMPlexGetConeSize(dm, cStart, &coneSize);
10314: DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);
10315: switch (dim) {
10316: case 1:
10317: switch (coneSize) {
10318: case 2:
10319: *cellRefiner = REFINER_SIMPLEX_1D;
10320: break;
10321: default:
10322: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10323: }
10324: break;
10325: case 2:
10326: switch (coneSize) {
10327: case 3:
10328: if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D;
10329: else *cellRefiner = REFINER_SIMPLEX_2D;
10330: break;
10331: case 4:
10332: if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D;
10333: else *cellRefiner = REFINER_HEX_2D;
10334: break;
10335: default:
10336: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10337: }
10338: break;
10339: case 3:
10340: switch (coneSize) {
10341: case 4:
10342: if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
10343: else *cellRefiner = REFINER_SIMPLEX_3D;
10344: break;
10345: case 5:
10346: if (cMax == 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
10347: else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10348: break;
10349: case 6:
10350: if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D;
10351: else *cellRefiner = REFINER_HEX_3D;
10352: break;
10353: default:
10354: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10355: }
10356: break;
10357: default:
10358: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %D for cell refiner", dim);
10359: }
10360: return(0);
10361: }
10363: PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined)
10364: {
10365: PetscBool isUniform;
10369: DMPlexGetRefinementUniform(dm, &isUniform);
10370: if (isUniform) {
10371: CellRefiner cellRefiner;
10372: PetscBool localized;
10374: DMGetCoordinatesLocalized(dm, &localized);
10375: DMPlexGetCellRefiner_Internal(dm, &cellRefiner);
10376: DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);
10377: DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);
10378: DMCopyBoundary(dm, *dmRefined);
10379: if (localized) {DMLocalizeCoordinates(*dmRefined);}
10380: } else {
10381: DMPlexRefine_Internal(dm, NULL, dmRefined);
10382: }
10383: return(0);
10384: }
10386: PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[])
10387: {
10388: DM cdm = dm;
10389: PetscInt r;
10390: PetscBool isUniform, localized;
10394: DMPlexGetRefinementUniform(dm, &isUniform);
10395: DMGetCoordinatesLocalized(dm, &localized);
10396: if (isUniform) {
10397: for (r = 0; r < nlevels; ++r) {
10398: CellRefiner cellRefiner;
10400: DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);
10401: DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);
10402: DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);
10403: DMSetRefineLevel(dmRefined[r], cdm->levelup+1);
10404: DMCopyBoundary(cdm, dmRefined[r]);
10405: if (localized) {DMLocalizeCoordinates(dmRefined[r]);}
10406: DMSetCoarseDM(dmRefined[r], cdm);
10407: DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);
10408: cdm = dmRefined[r];
10409: }
10410: } else {
10411: for (r = 0; r < nlevels; ++r) {
10412: DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);
10413: DMCopyBoundary(cdm, dmRefined[r]);
10414: if (localized) {DMLocalizeCoordinates(dmRefined[r]);}
10415: DMSetCoarseDM(dmRefined[r], cdm);
10416: cdm = dmRefined[r];
10417: }
10418: }
10419: return(0);
10420: }