Actual source code: plexrefine.c
petsc-3.12.5 2020-03-29
1: #include <petsc/private/dmpleximpl.h>
2: #include <petscsf.h>
4: const char * const CellRefiners[] = {"NOOP", "SIMPLEX_1D", "SIMPLEX_2D", "HYBRID_SIMPLEX_2D", "SIMPLEX_TO_HEX_2D", "HYBRID_SIMPLEX_TO_HEX_2D", "HEX_2D", "HYBRID_HEX_2D",
5: "SIMPLEX_3D", "HYBRID_SIMPLEX_3D", "SIMPLEX_TO_HEX_3D", "HYBRID_SIMPLEX_TO_HEX_3D", "HEX_3D", "HYBRID_HEX_3D", "CellRefiners", "REFINER_", 0};
7: PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart)
8: {
10: if (cStart) *cStart = 0;
11: if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth];
12: if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
13: if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
14: return(0);
15: }
17: PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd)
18: {
20: if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth];
21: if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
22: if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
23: if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1];
24: return(0);
25: }
27: /*
28: Note that j and invj are non-square:
29: v0 + j x_face = x_cell
30: invj (x_cell - v0) = x_face
31: */
32: PetscErrorCode CellRefinerGetAffineFaceTransforms_Internal(CellRefiner refiner, PetscInt *numFaces, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[], PetscReal *detj[])
33: {
34: PetscReal *v = NULL, *j = NULL, *invj = NULL, *dj = NULL;
35: PetscInt cdim, fdim;
39: switch (refiner) {
40: case REFINER_NOOP: break;
41: case REFINER_SIMPLEX_2D:
42: /*
43: 2
44: |\
45: | \
46: | \
47: | \
48: | \
49: | \
50: | \
51: 2 1
52: | \
53: | \
54: | \
55: 0---0-------1
56: */
57: cdim = 2;
58: fdim = 1;
59: if (numFaces) *numFaces = 3;
60: if (v0) {
61: PetscMalloc1(3*cdim, &v);
62: PetscMalloc1(3*cdim*fdim, &j);
63: PetscMalloc1(3*cdim*fdim, &invj);
64: PetscMalloc1(3, &dj);
65: /* 0 */
66: v[0+0] = 0.0; v[0+1] = -1.0;
67: j[0+0] = 1.0;
68: j[0+1] = 0.0;
69: invj[0+0] = 1.0; invj[0+1] = 0.0;
70: dj[0] = 1.0;
71: /* 1 */
72: v[2+0] = 0.0; v[2+1] = 0.0;
73: j[2+0] = -1.0;
74: j[2+1] = 1.0;
75: invj[2+0] = -0.5; invj[2+1] = 0.5;
76: dj[1] = 1.414213562373095;
77: /* 2 */
78: v[4+0] = -1.0; v[4+1] = 0.0;
79: j[4+0] = 0.0;
80: j[4+1] = -1.0;
81: invj[4+0] = 0.0; invj[4+1] = -1.0;
82: dj[2] = 1.0;
83: }
84: break;
85: case REFINER_HEX_2D:
86: /*
87: 3---------2---------2
88: | |
89: | |
90: | |
91: 3 1
92: | |
93: | |
94: | |
95: 0---------0---------1
96: */
97: cdim = 2;
98: fdim = 1;
99: if (numFaces) *numFaces = 4;
100: if (v0) {
101: PetscMalloc1(4*cdim, &v);
102: PetscMalloc1(4*cdim*fdim, &j);
103: PetscMalloc1(4*cdim*fdim, &invj);
104: PetscMalloc1(4, &dj);
105: /* 0 */
106: v[0+0] = 0.0; v[0+1] = -1.0;
107: j[0+0] = 1.0;
108: j[0+1] = 0.0;
109: invj[0+0] = 1.0; invj[0+1] = 0.0;
110: dj[0] = 1.0;
111: /* 1 */
112: v[2+0] = 1.0; v[2+1] = 0.0;
113: j[2+0] = 0.0;
114: j[2+1] = 1.0;
115: invj[2+0] = 0.0; invj[2+1] = 1.0;
116: dj[1] = 1.0;
117: /* 2 */
118: v[4+0] = 0.0; v[4+1] = 1.0;
119: j[4+0] = -1.0;
120: j[4+1] = 0.0;
121: invj[4+0] = -1.0; invj[4+1] = 0.0;
122: dj[2] = 1.0;
123: /* 3 */
124: v[6+0] = -1.0; v[6+1] = 0.0;
125: j[6+0] = 0.0;
126: j[6+1] = -1.0;
127: invj[6+0] = 0.0; invj[6+1] = -1.0;
128: dj[3] = 1.0;
129: }
130: break;
131: default:
132: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
133: }
134: if (v0) {*v0 = v;}
135: else {PetscFree(v);}
136: if (jac) {*jac = j;}
137: else {PetscFree(j);}
138: if (invjac) {*invjac = invj;}
139: else {PetscFree(invj);}
140: if (invjac) {*invjac = invj;}
141: else {PetscFree(invj);}
142: if (detj) {*detj = dj;}
143: else {PetscFree(dj);}
144: return(0);
145: }
147: /* Gets the affine map from the original cell to each subcell */
148: PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
149: {
150: PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ;
151: PetscInt dim, s;
155: switch (refiner) {
156: case REFINER_NOOP: break;
157: case REFINER_SIMPLEX_2D:
158: /*
159: 2
160: |\
161: | \
162: | \
163: | \
164: | C \
165: | \
166: | \
167: 2---1---1
168: |\ D / \
169: | 2 0 \
170: |A \ / B \
171: 0---0-------1
172: */
173: dim = 2;
174: if (numSubcells) *numSubcells = 4;
175: if (v0) {
176: PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);
177: /* A */
178: v[0+0] = -1.0; v[0+1] = -1.0;
179: j[0+0] = 0.5; j[0+1] = 0.0;
180: j[0+2] = 0.0; j[0+3] = 0.5;
181: /* B */
182: v[2+0] = 0.0; v[2+1] = -1.0;
183: j[4+0] = 0.5; j[4+1] = 0.0;
184: j[4+2] = 0.0; j[4+3] = 0.5;
185: /* C */
186: v[4+0] = -1.0; v[4+1] = 0.0;
187: j[8+0] = 0.5; j[8+1] = 0.0;
188: j[8+2] = 0.0; j[8+3] = 0.5;
189: /* D */
190: v[6+0] = 0.0; v[6+1] = -1.0;
191: j[12+0] = 0.0; j[12+1] = -0.5;
192: j[12+2] = 0.5; j[12+3] = 0.5;
193: for (s = 0; s < 4; ++s) {
194: DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
195: DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
196: }
197: }
198: break;
199: case REFINER_HEX_2D:
200: /*
201: 3---------2---------2
202: | | |
203: | D 2 C |
204: | | |
205: 3----3----0----1----1
206: | | |
207: | A 0 B |
208: | | |
209: 0---------0---------1
210: */
211: dim = 2;
212: if (numSubcells) *numSubcells = 4;
213: if (v0) {
214: PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);
215: /* A */
216: v[0+0] = -1.0; v[0+1] = -1.0;
217: j[0+0] = 0.5; j[0+1] = 0.0;
218: j[0+2] = 0.0; j[0+3] = 0.5;
219: /* B */
220: v[2+0] = 0.0; v[2+1] = -1.0;
221: j[4+0] = 0.5; j[4+1] = 0.0;
222: j[4+2] = 0.0; j[4+3] = 0.5;
223: /* C */
224: v[4+0] = 0.0; v[4+1] = 0.0;
225: j[8+0] = 0.5; j[8+1] = 0.0;
226: j[8+2] = 0.0; j[8+3] = 0.5;
227: /* D */
228: v[6+0] = -1.0; v[6+1] = 0.0;
229: j[12+0] = 0.5; j[12+1] = 0.0;
230: j[12+2] = 0.0; j[12+3] = 0.5;
231: for (s = 0; s < 4; ++s) {
232: DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
233: DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
234: }
235: }
236: break;
237: case REFINER_HEX_3D:
238: /*
239: Bottom (viewed from top) Top
240: 1---------2---------2 7---------2---------6
241: | | | | | |
242: | B 2 C | | H 2 G |
243: | | | | | |
244: 3----3----0----1----1 3----3----0----1----1
245: | | | | | |
246: | A 0 D | | E 0 F |
247: | | | | | |
248: 0---------0---------3 4---------0---------5
249: */
250: dim = 3;
251: if (numSubcells) *numSubcells = 8;
252: if (v0) {
253: PetscMalloc3(8*dim,&v,8*dim*dim,&j,8*dim*dim,&invj);
254: /* A */
255: v[0+0] = -1.0; v[0+1] = -1.0; v[0+2] = -1.0;
256: j[0+0] = 0.5; j[0+1] = 0.0; j[0+2] = 0.0;
257: j[0+3] = 0.0; j[0+4] = 0.5; j[0+5] = 0.0;
258: j[0+6] = 0.0; j[0+7] = 0.0; j[0+8] = 0.5;
259: /* B */
260: v[3+0] = -1.0; v[3+1] = 0.0; v[3+2] = -1.0;
261: j[9+0] = 0.5; j[9+1] = 0.0; j[9+2] = 0.0;
262: j[9+3] = 0.0; j[9+4] = 0.5; j[9+5] = 0.0;
263: j[9+6] = 0.0; j[9+7] = 0.0; j[9+8] = 0.5;
264: /* C */
265: v[6+0] = 0.0; v[6+1] = 0.0; v[6+2] = -1.0;
266: j[18+0] = 0.5; j[18+1] = 0.0; j[18+2] = 0.0;
267: j[18+3] = 0.0; j[18+4] = 0.5; j[18+5] = 0.0;
268: j[18+6] = 0.0; j[18+7] = 0.0; j[18+8] = 0.5;
269: /* D */
270: v[9+0] = 0.0; v[9+1] = -1.0; v[9+2] = -1.0;
271: j[27+0] = 0.5; j[27+1] = 0.0; j[27+2] = 0.0;
272: j[27+3] = 0.0; j[27+4] = 0.5; j[27+5] = 0.0;
273: j[27+6] = 0.0; j[27+7] = 0.0; j[27+8] = 0.5;
274: /* E */
275: v[12+0] = -1.0; v[12+1] = -1.0; v[12+2] = 0.0;
276: j[36+0] = 0.5; j[36+1] = 0.0; j[36+2] = 0.0;
277: j[36+3] = 0.0; j[36+4] = 0.5; j[36+5] = 0.0;
278: j[36+6] = 0.0; j[36+7] = 0.0; j[36+8] = 0.5;
279: /* F */
280: v[15+0] = 0.0; v[15+1] = -1.0; v[15+2] = 0.0;
281: j[45+0] = 0.5; j[45+1] = 0.0; j[45+2] = 0.0;
282: j[45+3] = 0.0; j[45+4] = 0.5; j[45+5] = 0.0;
283: j[45+6] = 0.0; j[45+7] = 0.0; j[45+8] = 0.5;
284: /* G */
285: v[18+0] = 0.0; v[18+1] = 0.0; v[18+2] = 0.0;
286: j[54+0] = 0.5; j[54+1] = 0.0; j[54+2] = 0.0;
287: j[54+3] = 0.0; j[54+4] = 0.5; j[54+5] = 0.0;
288: j[54+6] = 0.0; j[54+7] = 0.0; j[54+8] = 0.5;
289: /* H */
290: v[21+0] = -1.0; v[21+1] = 0.0; v[21+2] = 0.0;
291: j[63+0] = 0.5; j[63+1] = 0.0; j[63+2] = 0.0;
292: j[63+3] = 0.0; j[63+4] = 0.5; j[63+5] = 0.0;
293: j[63+6] = 0.0; j[63+7] = 0.0; j[63+8] = 0.5;
294: for (s = 0; s < 8; ++s) {
295: DMPlex_Det3D_Internal(&detJ, &j[s*dim*dim]);
296: DMPlex_Invert3D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
297: }
298: }
299: break;
300: default:
301: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
302: }
303: if (v0) {*v0 = v; *jac = j; *invjac = invj;}
304: return(0);
305: }
307: PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
308: {
312: PetscFree3(*v0,*jac,*invjac);
313: return(0);
314: }
316: /* Should this be here or in the DualSpace somehow? */
317: PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside)
318: {
319: PetscReal sum = 0.0;
320: PetscInt d;
323: *inside = PETSC_TRUE;
324: switch (refiner) {
325: case REFINER_NOOP: break;
326: case REFINER_SIMPLEX_2D:
327: for (d = 0; d < 2; ++d) {
328: if (point[d] < -1.0) {*inside = PETSC_FALSE; break;}
329: sum += point[d];
330: }
331: if (sum > 1.0e-10) {*inside = PETSC_FALSE; break;}
332: break;
333: case REFINER_HEX_2D:
334: for (d = 0; d < 2; ++d) if ((point[d] < -1.00000000001) || (point[d] > 1.000000000001)) {*inside = PETSC_FALSE; break;}
335: break;
336: case REFINER_HEX_3D:
337: for (d = 0; d < 3; d++) if (PetscAbsReal(point[d]) > 1 + PETSC_SMALL) {*inside = PETSC_FALSE; break;}
338: break;
339: default:
340: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
341: }
342: return(0);
343: }
345: static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
346: {
347: PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
351: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
352: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
353: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
354: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
355: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
356: switch (refiner) {
357: case REFINER_NOOP:
358: break;
359: case REFINER_SIMPLEX_1D:
360: depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */
361: depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */
362: break;
363: case REFINER_SIMPLEX_2D:
364: depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */
365: depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */
366: depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
367: break;
368: case REFINER_HYBRID_SIMPLEX_2D:
369: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
370: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
371: depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */
372: depthSize[1] = 2*(fMax - fStart) + 3*(cMax - cStart) + (fEnd - fMax) + (cEnd - cMax); /* Every interior face is split into 2 faces, 3 faces are added for each interior cell, and one in each hybrid cell */
373: depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, hybrid cells split into 2 cells */
374: break;
375: case REFINER_SIMPLEX_TO_HEX_2D:
376: depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
377: depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */
378: depthSize[2] = 3*(cEnd - cStart); /* Every cell split into 3 cells */
379: break;
380: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
381: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
382: depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
383: depthSize[1] = 2*(fEnd - fStart) + 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every face is split into 2 faces and 3 faces are added for each cell. 4 for each hybrid cell */
384: depthSize[2] = 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every cell split into 3 cells, hybrid cells split in 4 */
385: break;
386: case REFINER_HEX_2D:
387: depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
388: depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */
389: depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
390: break;
391: case REFINER_HYBRID_HEX_2D:
392: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
393: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
394: /* Quadrilateral */
395: depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */
396: depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */
397: depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */
398: /* Segment Prisms */
399: depthSize[0] += 0; /* No hybrid vertices */
400: depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */
401: depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */
402: break;
403: case REFINER_SIMPLEX_3D:
404: depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */
405: depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + (cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 1 edge for each cell */
406: depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */
407: depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */
408: break;
409: case REFINER_HYBRID_SIMPLEX_3D:
410: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
411: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
412: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
413: /* Tetrahedra */
414: depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */
415: depthSize[1] = 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 1 edge for each interior cell */
416: depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */
417: depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */
418: /* Triangular Prisms */
419: depthSize[0] += 0; /* No hybrid vertices */
420: depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */
421: depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */
422: depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */
423: break;
424: case REFINER_SIMPLEX_TO_HEX_3D:
425: depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */
426: depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + 4*(cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 4 for each cell */
427: depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */
428: depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
429: break;
430: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
431: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
432: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
433: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
434: /* Tetrahedra */
435: depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every interior edge, face and cell */
436: depthSize[1] = 2*(eMax - eStart) + 3*(fMax - fStart) + 4*(cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 4 edges for each interior cell */
437: depthSize[2] = 3*(fMax - fStart) + 6*(cMax - cStart); /* Every interior face split into 3 faces, 6 faces added for each interior cell */
438: depthSize[3] = 4*(cMax - cStart); /* Every interior cell split into 8 cells */
439: /* Triangular Prisms */
440: depthSize[0] += 0; /* No hybrid vertices */
441: depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and cell */
442: depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */
443: depthSize[3] += 3*(cEnd - cMax); /* Every hybrid cell split into 3 cells */
444: break;
445: case REFINER_HEX_3D:
446: depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
447: depthSize[1] = 2*(eEnd - eStart) + 4*(fEnd - fStart) + 6*(cEnd - cStart); /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */
448: depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */
449: depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */
450: break;
451: case REFINER_HYBRID_HEX_3D:
452: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
453: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
454: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
455: /* Hexahedra */
456: depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
457: depthSize[1] = 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart); /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */
458: depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */
459: depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */
460: /* Quadrilateral Prisms */
461: depthSize[0] += 0; /* No hybrid vertices */
462: depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
463: depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */
464: depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */
465: break;
466: default:
467: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
468: }
469: return(0);
470: }
472: /* Return triangle edge for orientation o, if it is r for o == 0 */
473: PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
474: return (o < 0 ? 2-(o+r) : o+r)%3;
475: }
476: PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
477: return (o < 0 ? 2-(o+s) : 3+s-o)%3;
478: }
480: /* Return triangle subface for orientation o, if it is r for o == 0 */
481: PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
482: return (o < 0 ? 3-(o+r) : o+r)%3;
483: }
484: PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
485: return (o < 0 ? 3-(o+s) : 3+s-o)%3;
486: }
488: /* Return the interior edge number connecting the midpoints of the triangle edges r
489: and r+1 in the transitive closure for triangle orientation o */
490: PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) {
491: return (o < 0 ? 1-(o+r) : o+r)%3;
492: }
493: PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) {
494: return (o < 0 ? 1-(o+s) : 3+s-o)%3;
495: }
497: /* Return the interior edge number connecting the midpoint of the triangle edge r
498: (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */
499: PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) {
500: return (o < 0 ? 2-(o+r) : o+r)%3;
501: }
502: PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) {
503: return (o < 0 ? 2-(o+s) : 3+s-o)%3;
504: }
506: /* Return quad edge for orientation o, if it is r for o == 0 */
507: PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
508: return (o < 0 ? 3-(o+r) : o+r)%4;
509: }
510: PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
511: return (o < 0 ? 3-(o+s) : 4+s-o)%4;
512: }
514: /* Return quad subface for orientation o, if it is r for o == 0 */
515: PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
516: return (o < 0 ? 4-(o+r) : o+r)%4;
517: }
518: PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
519: return (o < 0 ? 4-(o+s) : 4+s-o)%4;
520: }
522: static PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd)
523: {
524: IS cIS;
528: ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);
529: DMLabelSetStratumIS(label, value, cIS);
530: ISDestroy(&cIS);
531: return(0);
532: }
534: static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
535: {
536: PetscInt depth, cStart, cStartNew, cEnd, cEndNew, cMax, c, vStart, vStartNew, vEnd, vEndNew, vMax, v, fStart, fStartNew, fEnd, fEndNew, fMax, f, eStart, eStartNew, eEnd, eEndNew, eMax, e, r;
537: DMLabel depthLabel;
541: DMPlexGetDepth(dm, &depth);
542: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
543: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
544: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
545: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
546: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
547: GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);
548: GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);
549: DMCreateLabel(rdm,"depth");
550: DMPlexGetDepthLabel(rdm,&depthLabel);
551: DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);
552: if (depth > 2) DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);
553: if (depth > 1) DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);
554: if (depth > 0) DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);
555: {
556: DM_Plex *plex = (DM_Plex *) rdm->data;
557: PetscObjectStateGet((PetscObject) depthLabel, &plex->depthState);
558: }
559: if (!refiner) return(0);
560: switch (refiner) {
561: case REFINER_SIMPLEX_1D:
562: /* All cells have 2 vertices */
563: for (c = cStart; c < cEnd; ++c) {
564: for (r = 0; r < 2; ++r) {
565: const PetscInt newp = cStartNew + (c - cStart)*2 + r;
567: DMPlexSetConeSize(rdm, newp, 2);
568: }
569: }
570: /* Old vertices have identical supports */
571: for (v = vStart; v < vEnd; ++v) {
572: const PetscInt newp = vStartNew + (v - vStart);
573: PetscInt size;
575: DMPlexGetSupportSize(dm, v, &size);
576: DMPlexSetSupportSize(rdm, newp, size);
577: }
578: /* Cell vertices have support 2 */
579: for (c = cStart; c < cEnd; ++c) {
580: const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart);
582: DMPlexSetSupportSize(rdm, newp, 2);
583: }
584: break;
585: case REFINER_SIMPLEX_2D:
586: /* All cells have 3 faces */
587: for (c = cStart; c < cEnd; ++c) {
588: for (r = 0; r < 4; ++r) {
589: const PetscInt newp = (c - cStart)*4 + r;
591: DMPlexSetConeSize(rdm, newp, 3);
592: }
593: }
594: /* Split faces have 2 vertices and the same cells as the parent */
595: for (f = fStart; f < fEnd; ++f) {
596: for (r = 0; r < 2; ++r) {
597: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
598: PetscInt size;
600: DMPlexSetConeSize(rdm, newp, 2);
601: DMPlexGetSupportSize(dm, f, &size);
602: DMPlexSetSupportSize(rdm, newp, size);
603: }
604: }
605: /* Interior faces have 2 vertices and 2 cells */
606: for (c = cStart; c < cEnd; ++c) {
607: for (r = 0; r < 3; ++r) {
608: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
610: DMPlexSetConeSize(rdm, newp, 2);
611: DMPlexSetSupportSize(rdm, newp, 2);
612: }
613: }
614: /* Old vertices have identical supports */
615: for (v = vStart; v < vEnd; ++v) {
616: const PetscInt newp = vStartNew + (v - vStart);
617: PetscInt size;
619: DMPlexGetSupportSize(dm, v, &size);
620: DMPlexSetSupportSize(rdm, newp, size);
621: }
622: /* Face vertices have 2 + cells*2 supports */
623: for (f = fStart; f < fEnd; ++f) {
624: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
625: PetscInt size;
627: DMPlexGetSupportSize(dm, f, &size);
628: DMPlexSetSupportSize(rdm, newp, 2 + size*2);
629: }
630: break;
631: case REFINER_SIMPLEX_TO_HEX_2D:
632: /* All cells have 4 faces */
633: for (c = cStart; c < cEnd; ++c) {
634: for (r = 0; r < 3; ++r) {
635: const PetscInt newp = (c - cStart)*3 + r;
637: DMPlexSetConeSize(rdm, newp, 4);
638: }
639: }
640: /* Split faces have 2 vertices and the same cells as the parent */
641: for (f = fStart; f < fEnd; ++f) {
642: for (r = 0; r < 2; ++r) {
643: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
644: PetscInt size;
646: DMPlexSetConeSize(rdm, newp, 2);
647: DMPlexGetSupportSize(dm, f, &size);
648: DMPlexSetSupportSize(rdm, newp, size);
649: }
650: }
651: /* Interior faces have 2 vertices and 2 cells */
652: for (c = cStart; c < cEnd; ++c) {
653: for (r = 0; r < 3; ++r) {
654: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
656: DMPlexSetConeSize(rdm, newp, 2);
657: DMPlexSetSupportSize(rdm, newp, 2);
658: }
659: }
660: /* Old vertices have identical supports */
661: for (v = vStart; v < vEnd; ++v) {
662: const PetscInt newp = vStartNew + (v - vStart);
663: PetscInt size;
665: DMPlexGetSupportSize(dm, v, &size);
666: DMPlexSetSupportSize(rdm, newp, size);
667: }
668: /* Split-face vertices have cells + 2 supports */
669: for (f = fStart; f < fEnd; ++f) {
670: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
671: PetscInt size;
673: DMPlexGetSupportSize(dm, f, &size);
674: DMPlexSetSupportSize(rdm, newp, size + 2);
675: }
676: /* Interior vertices have 3 supports */
677: for (c = cStart; c < cEnd; ++c) {
678: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
680: DMPlexSetSupportSize(rdm, newp, 3);
681: }
682: break;
683: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
684: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
685: /* the mesh is no longer hybrid */
686: cMax = PetscMin(cEnd, cMax);
687: /* All cells have 4 faces */
688: for (c = cStart; c < cMax; ++c) {
689: for (r = 0; r < 3; ++r) {
690: const PetscInt newp = (c - cStart)*3 + r;
692: DMPlexSetConeSize(rdm, newp, 4);
693: }
694: }
695: for (c = cMax; c < cEnd; ++c) {
696: for (r = 0; r < 4; ++r) {
697: const PetscInt newp = (cMax - cStart)*3 + (c - cMax)*4 + r;
699: DMPlexSetConeSize(rdm, newp, 4);
700: }
701: }
702: /* Split faces have 2 vertices and the same cells as the parent */
703: for (f = fStart; f < fEnd; ++f) {
704: for (r = 0; r < 2; ++r) {
705: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
706: PetscInt size;
708: DMPlexSetConeSize(rdm, newp, 2);
709: DMPlexGetSupportSize(dm, f, &size);
710: DMPlexSetSupportSize(rdm, newp, size);
711: }
712: }
713: /* Interior faces have 2 vertices and 2 cells */
714: for (c = cStart; c < cMax; ++c) {
715: for (r = 0; r < 3; ++r) {
716: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
718: DMPlexSetConeSize(rdm, newp, 2);
719: DMPlexSetSupportSize(rdm, newp, 2);
720: }
721: }
722: /* Hybrid interior faces have 2 vertices and 2 cells */
723: for (c = cMax; c < cEnd; ++c) {
724: for (r = 0; r < 4; ++r) {
725: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r;
727: DMPlexSetConeSize(rdm, newp, 2);
728: DMPlexSetSupportSize(rdm, newp, 2);
729: }
730: }
731: /* Old vertices have identical supports */
732: for (v = vStart; v < vEnd; ++v) {
733: const PetscInt newp = vStartNew + (v - vStart);
734: PetscInt size;
736: DMPlexGetSupportSize(dm, v, &size);
737: DMPlexSetSupportSize(rdm, newp, size);
738: }
739: /* Split-face vertices have cells + 2 supports */
740: for (f = fStart; f < fEnd; ++f) {
741: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
742: PetscInt size;
744: DMPlexGetSupportSize(dm, f, &size);
745: DMPlexSetSupportSize(rdm, newp, size + 2);
746: }
747: /* Interior vertices have 3 supports */
748: for (c = cStart; c < cMax; ++c) {
749: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
751: DMPlexSetSupportSize(rdm, newp, 3);
752: }
753: /* Hybrid interior vertices have 4 supports */
754: for (c = cMax; c < cEnd; ++c) {
755: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
757: DMPlexSetSupportSize(rdm, newp, 4);
758: }
759: break;
760: case REFINER_HEX_2D:
761: /* All cells have 4 faces */
762: for (c = cStart; c < cEnd; ++c) {
763: for (r = 0; r < 4; ++r) {
764: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
766: DMPlexSetConeSize(rdm, newp, 4);
767: }
768: }
769: /* Split faces have 2 vertices and the same cells as the parent */
770: for (f = fStart; f < fEnd; ++f) {
771: for (r = 0; r < 2; ++r) {
772: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
773: PetscInt size;
775: DMPlexSetConeSize(rdm, newp, 2);
776: DMPlexGetSupportSize(dm, f, &size);
777: DMPlexSetSupportSize(rdm, newp, size);
778: }
779: }
780: /* Interior faces have 2 vertices and 2 cells */
781: for (c = cStart; c < cEnd; ++c) {
782: for (r = 0; r < 4; ++r) {
783: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
785: DMPlexSetConeSize(rdm, newp, 2);
786: DMPlexSetSupportSize(rdm, newp, 2);
787: }
788: }
789: /* Old vertices have identical supports */
790: for (v = vStart; v < vEnd; ++v) {
791: const PetscInt newp = vStartNew + (v - vStart);
792: PetscInt size;
794: DMPlexGetSupportSize(dm, v, &size);
795: DMPlexSetSupportSize(rdm, newp, size);
796: }
797: /* Face vertices have 2 + cells supports */
798: for (f = fStart; f < fEnd; ++f) {
799: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
800: PetscInt size;
802: DMPlexGetSupportSize(dm, f, &size);
803: DMPlexSetSupportSize(rdm, newp, 2 + size);
804: }
805: /* Cell vertices have 4 supports */
806: for (c = cStart; c < cEnd; ++c) {
807: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
809: DMPlexSetSupportSize(rdm, newp, 4);
810: }
811: break;
812: case REFINER_HYBRID_SIMPLEX_2D:
813: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
814: cMax = PetscMin(cEnd, cMax);
815: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
816: fMax = PetscMin(fEnd, fMax);
817: DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);
818: /* Interior cells have 3 faces */
819: for (c = cStart; c < cMax; ++c) {
820: for (r = 0; r < 4; ++r) {
821: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
823: DMPlexSetConeSize(rdm, newp, 3);
824: }
825: }
826: /* Hybrid cells have 4 faces */
827: for (c = cMax; c < cEnd; ++c) {
828: for (r = 0; r < 2; ++r) {
829: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
831: DMPlexSetConeSize(rdm, newp, 4);
832: }
833: }
834: /* Interior split faces have 2 vertices and the same cells as the parent */
835: for (f = fStart; f < fMax; ++f) {
836: for (r = 0; r < 2; ++r) {
837: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
838: PetscInt size;
840: DMPlexSetConeSize(rdm, newp, 2);
841: DMPlexGetSupportSize(dm, f, &size);
842: DMPlexSetSupportSize(rdm, newp, size);
843: }
844: }
845: /* Interior cell faces have 2 vertices and 2 cells */
846: for (c = cStart; c < cMax; ++c) {
847: for (r = 0; r < 3; ++r) {
848: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
850: DMPlexSetConeSize(rdm, newp, 2);
851: DMPlexSetSupportSize(rdm, newp, 2);
852: }
853: }
854: /* Hybrid faces have 2 vertices and the same cells */
855: for (f = fMax; f < fEnd; ++f) {
856: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
857: PetscInt size;
859: DMPlexSetConeSize(rdm, newp, 2);
860: DMPlexGetSupportSize(dm, f, &size);
861: DMPlexSetSupportSize(rdm, newp, size);
862: }
863: /* Hybrid cell faces have 2 vertices and 2 cells */
864: for (c = cMax; c < cEnd; ++c) {
865: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
867: DMPlexSetConeSize(rdm, newp, 2);
868: DMPlexSetSupportSize(rdm, newp, 2);
869: }
870: /* Old vertices have identical supports */
871: for (v = vStart; v < vEnd; ++v) {
872: const PetscInt newp = vStartNew + (v - vStart);
873: PetscInt size;
875: DMPlexGetSupportSize(dm, v, &size);
876: DMPlexSetSupportSize(rdm, newp, size);
877: }
878: /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
879: for (f = fStart; f < fMax; ++f) {
880: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
881: const PetscInt *support;
882: PetscInt size, newSize = 2, s;
884: DMPlexGetSupportSize(dm, f, &size);
885: DMPlexGetSupport(dm, f, &support);
886: for (s = 0; s < size; ++s) {
887: if (support[s] >= cMax) newSize += 1;
888: else newSize += 2;
889: }
890: DMPlexSetSupportSize(rdm, newp, newSize);
891: }
892: break;
893: case REFINER_HYBRID_HEX_2D:
894: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
895: cMax = PetscMin(cEnd, cMax);
896: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
897: fMax = PetscMin(fEnd, fMax);
898: DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);
899: /* Interior cells have 4 faces */
900: for (c = cStart; c < cMax; ++c) {
901: for (r = 0; r < 4; ++r) {
902: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
904: DMPlexSetConeSize(rdm, newp, 4);
905: }
906: }
907: /* Hybrid cells have 4 faces */
908: for (c = cMax; c < cEnd; ++c) {
909: for (r = 0; r < 2; ++r) {
910: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
912: DMPlexSetConeSize(rdm, newp, 4);
913: }
914: }
915: /* Interior split faces have 2 vertices and the same cells as the parent */
916: for (f = fStart; f < fMax; ++f) {
917: for (r = 0; r < 2; ++r) {
918: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
919: PetscInt size;
921: DMPlexSetConeSize(rdm, newp, 2);
922: DMPlexGetSupportSize(dm, f, &size);
923: DMPlexSetSupportSize(rdm, newp, size);
924: }
925: }
926: /* Interior cell faces have 2 vertices and 2 cells */
927: for (c = cStart; c < cMax; ++c) {
928: for (r = 0; r < 4; ++r) {
929: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
931: DMPlexSetConeSize(rdm, newp, 2);
932: DMPlexSetSupportSize(rdm, newp, 2);
933: }
934: }
935: /* Hybrid faces have 2 vertices and the same cells */
936: for (f = fMax; f < fEnd; ++f) {
937: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
938: PetscInt size;
940: DMPlexSetConeSize(rdm, newp, 2);
941: DMPlexGetSupportSize(dm, f, &size);
942: DMPlexSetSupportSize(rdm, newp, size);
943: }
944: /* Hybrid cell faces have 2 vertices and 2 cells */
945: for (c = cMax; c < cEnd; ++c) {
946: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
948: DMPlexSetConeSize(rdm, newp, 2);
949: DMPlexSetSupportSize(rdm, newp, 2);
950: }
951: /* Old vertices have identical supports */
952: for (v = vStart; v < vEnd; ++v) {
953: const PetscInt newp = vStartNew + (v - vStart);
954: PetscInt size;
956: DMPlexGetSupportSize(dm, v, &size);
957: DMPlexSetSupportSize(rdm, newp, size);
958: }
959: /* Face vertices have 2 + cells supports */
960: for (f = fStart; f < fMax; ++f) {
961: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
962: PetscInt size;
964: DMPlexGetSupportSize(dm, f, &size);
965: DMPlexSetSupportSize(rdm, newp, 2 + size);
966: }
967: /* Cell vertices have 4 supports */
968: for (c = cStart; c < cMax; ++c) {
969: const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
971: DMPlexSetSupportSize(rdm, newp, 4);
972: }
973: break;
974: case REFINER_SIMPLEX_3D:
975: /* All cells have 4 faces */
976: for (c = cStart; c < cEnd; ++c) {
977: for (r = 0; r < 8; ++r) {
978: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
980: DMPlexSetConeSize(rdm, newp, 4);
981: }
982: }
983: /* Split faces have 3 edges and the same cells as the parent */
984: for (f = fStart; f < fEnd; ++f) {
985: for (r = 0; r < 4; ++r) {
986: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
987: PetscInt size;
989: DMPlexSetConeSize(rdm, newp, 3);
990: DMPlexGetSupportSize(dm, f, &size);
991: DMPlexSetSupportSize(rdm, newp, size);
992: }
993: }
994: /* Interior cell faces have 3 edges and 2 cells */
995: for (c = cStart; c < cEnd; ++c) {
996: for (r = 0; r < 8; ++r) {
997: const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
999: DMPlexSetConeSize(rdm, newp, 3);
1000: DMPlexSetSupportSize(rdm, newp, 2);
1001: }
1002: }
1003: /* Split edges have 2 vertices and the same faces */
1004: for (e = eStart; e < eEnd; ++e) {
1005: for (r = 0; r < 2; ++r) {
1006: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1007: PetscInt size;
1009: DMPlexSetConeSize(rdm, newp, 2);
1010: DMPlexGetSupportSize(dm, e, &size);
1011: DMPlexSetSupportSize(rdm, newp, size);
1012: }
1013: }
1014: /* Face edges have 2 vertices and 2+cells*(1/2) faces */
1015: for (f = fStart; f < fEnd; ++f) {
1016: for (r = 0; r < 3; ++r) {
1017: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
1018: const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
1019: PetscInt coneSize, c, supportSize, s, er, intFaces = 0;
1021: DMPlexSetConeSize(rdm, newp, 2);
1022: DMPlexGetSupportSize(dm, f, &supportSize);
1023: DMPlexGetSupport(dm, f, &support);
1024: for (s = 0; s < supportSize; ++s) {
1025: DMPlexGetConeSize(dm, support[s], &coneSize);
1026: DMPlexGetCone(dm, support[s], &cone);
1027: DMPlexGetConeOrientation(dm, support[s], &ornt);
1028: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
1029: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
1030: er = GetTriMidEdgeInverse_Static(ornt[c], r);
1031: if (er == eint[c]) {
1032: intFaces += 1;
1033: } else {
1034: intFaces += 2;
1035: }
1036: }
1037: DMPlexSetSupportSize(rdm, newp, 2+intFaces);
1038: }
1039: }
1040: /* Interior cell edges have 2 vertices and 4 faces */
1041: for (c = cStart; c < cEnd; ++c) {
1042: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
1044: DMPlexSetConeSize(rdm, newp, 2);
1045: DMPlexSetSupportSize(rdm, newp, 4);
1046: }
1047: /* Old vertices have identical supports */
1048: for (v = vStart; v < vEnd; ++v) {
1049: const PetscInt newp = vStartNew + (v - vStart);
1050: PetscInt size;
1052: DMPlexGetSupportSize(dm, v, &size);
1053: DMPlexSetSupportSize(rdm, newp, size);
1054: }
1055: /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
1056: for (e = eStart; e < eEnd; ++e) {
1057: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1058: PetscInt size, *star = NULL, starSize, s, cellSize = 0;
1060: DMPlexGetSupportSize(dm, e, &size);
1061: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
1062: for (s = 0; s < starSize*2; s += 2) {
1063: const PetscInt *cone, *ornt;
1064: PetscInt e01, e23;
1066: if ((star[s] >= cStart) && (star[s] < cEnd)) {
1067: /* Check edge 0-1 */
1068: DMPlexGetCone(dm, star[s], &cone);
1069: DMPlexGetConeOrientation(dm, star[s], &ornt);
1070: DMPlexGetCone(dm, cone[0], &cone);
1071: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
1072: /* Check edge 2-3 */
1073: DMPlexGetCone(dm, star[s], &cone);
1074: DMPlexGetConeOrientation(dm, star[s], &ornt);
1075: DMPlexGetCone(dm, cone[2], &cone);
1076: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
1077: if ((e01 == e) || (e23 == e)) ++cellSize;
1078: }
1079: }
1080: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
1081: DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);
1082: }
1083: break;
1084: case REFINER_HYBRID_SIMPLEX_3D:
1085: DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
1086: eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);
1087: /* Interior cells have 4 faces */
1088: for (c = cStart; c < cMax; ++c) {
1089: for (r = 0; r < 8; ++r) {
1090: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
1092: DMPlexSetConeSize(rdm, newp, 4);
1093: }
1094: }
1095: /* Hybrid cells have 5 faces */
1096: for (c = cMax; c < cEnd; ++c) {
1097: for (r = 0; r < 4; ++r) {
1098: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
1100: DMPlexSetConeSize(rdm, newp, 5);
1101: }
1102: }
1103: /* Interior split faces have 3 edges and the same cells as the parent */
1104: for (f = fStart; f < fMax; ++f) {
1105: for (r = 0; r < 4; ++r) {
1106: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
1107: PetscInt size;
1109: DMPlexSetConeSize(rdm, newp, 3);
1110: DMPlexGetSupportSize(dm, f, &size);
1111: DMPlexSetSupportSize(rdm, newp, size);
1112: }
1113: }
1114: /* Interior cell faces have 3 edges and 2 cells */
1115: for (c = cStart; c < cMax; ++c) {
1116: for (r = 0; r < 8; ++r) {
1117: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
1119: DMPlexSetConeSize(rdm, newp, 3);
1120: DMPlexSetSupportSize(rdm, newp, 2);
1121: }
1122: }
1123: /* Hybrid split faces have 4 edges and the same cells as the parent */
1124: for (f = fMax; f < fEnd; ++f) {
1125: for (r = 0; r < 2; ++r) {
1126: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
1127: PetscInt size;
1129: DMPlexSetConeSize(rdm, newp, 4);
1130: DMPlexGetSupportSize(dm, f, &size);
1131: DMPlexSetSupportSize(rdm, newp, size);
1132: }
1133: }
1134: /* Hybrid cells faces have 4 edges and 2 cells */
1135: for (c = cMax; c < cEnd; ++c) {
1136: for (r = 0; r < 3; ++r) {
1137: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
1139: DMPlexSetConeSize(rdm, newp, 4);
1140: DMPlexSetSupportSize(rdm, newp, 2);
1141: }
1142: }
1143: /* Interior split edges have 2 vertices and the same faces */
1144: for (e = eStart; e < eMax; ++e) {
1145: for (r = 0; r < 2; ++r) {
1146: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1147: PetscInt size;
1149: DMPlexSetConeSize(rdm, newp, 2);
1150: DMPlexGetSupportSize(dm, e, &size);
1151: DMPlexSetSupportSize(rdm, newp, size);
1152: }
1153: }
1154: /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
1155: for (f = fStart; f < fMax; ++f) {
1156: for (r = 0; r < 3; ++r) {
1157: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
1158: const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
1159: PetscInt coneSize, c, supportSize, s, er, intFaces = 0;
1161: DMPlexSetConeSize(rdm, newp, 2);
1162: DMPlexGetSupportSize(dm, f, &supportSize);
1163: DMPlexGetSupport(dm, f, &support);
1164: for (s = 0; s < supportSize; ++s) {
1165: DMPlexGetConeSize(dm, support[s], &coneSize);
1166: DMPlexGetCone(dm, support[s], &cone);
1167: DMPlexGetConeOrientation(dm, support[s], &ornt);
1168: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
1169: if (support[s] < cMax) {
1170: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
1171: er = GetTriMidEdgeInverse_Static(ornt[c], r);
1172: if (er == eint[c]) {
1173: intFaces += 1;
1174: } else {
1175: intFaces += 2;
1176: }
1177: } else {
1178: intFaces += 1;
1179: }
1180: }
1181: DMPlexSetSupportSize(rdm, newp, 2+intFaces);
1182: }
1183: }
1184: /* Interior cell edges have 2 vertices and 4 faces */
1185: for (c = cStart; c < cMax; ++c) {
1186: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
1188: DMPlexSetConeSize(rdm, newp, 2);
1189: DMPlexSetSupportSize(rdm, newp, 4);
1190: }
1191: /* Hybrid edges have 2 vertices and the same faces */
1192: for (e = eMax; e < eEnd; ++e) {
1193: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
1194: PetscInt size;
1196: DMPlexSetConeSize(rdm, newp, 2);
1197: DMPlexGetSupportSize(dm, e, &size);
1198: DMPlexSetSupportSize(rdm, newp, size);
1199: }
1200: /* Hybrid face edges have 2 vertices and 2+2*cells faces */
1201: for (f = fMax; f < fEnd; ++f) {
1202: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
1203: PetscInt size;
1205: DMPlexSetConeSize(rdm, newp, 2);
1206: DMPlexGetSupportSize(dm, f, &size);
1207: DMPlexSetSupportSize(rdm, newp, 2+2*size);
1208: }
1209: /* Interior vertices have identical supports */
1210: for (v = vStart; v < vEnd; ++v) {
1211: const PetscInt newp = vStartNew + (v - vStart);
1212: PetscInt size;
1214: DMPlexGetSupportSize(dm, v, &size);
1215: DMPlexSetSupportSize(rdm, newp, size);
1216: }
1217: /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
1218: for (e = eStart; e < eMax; ++e) {
1219: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1220: const PetscInt *support;
1221: PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
1223: DMPlexGetSupportSize(dm, e, &size);
1224: DMPlexGetSupport(dm, e, &support);
1225: for (s = 0; s < size; ++s) {
1226: if (support[s] < fMax) faceSize += 2;
1227: else faceSize += 1;
1228: }
1229: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
1230: for (s = 0; s < starSize*2; s += 2) {
1231: const PetscInt *cone, *ornt;
1232: PetscInt e01, e23;
1234: if ((star[s] >= cStart) && (star[s] < cMax)) {
1235: /* Check edge 0-1 */
1236: DMPlexGetCone(dm, star[s], &cone);
1237: DMPlexGetConeOrientation(dm, star[s], &ornt);
1238: DMPlexGetCone(dm, cone[0], &cone);
1239: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
1240: /* Check edge 2-3 */
1241: DMPlexGetCone(dm, star[s], &cone);
1242: DMPlexGetConeOrientation(dm, star[s], &ornt);
1243: DMPlexGetCone(dm, cone[2], &cone);
1244: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
1245: if ((e01 == e) || (e23 == e)) ++cellSize;
1246: }
1247: }
1248: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
1249: DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);
1250: }
1251: break;
1252: case REFINER_SIMPLEX_TO_HEX_3D:
1253: /* All cells have 6 faces */
1254: for (c = cStart; c < cEnd; ++c) {
1255: for (r = 0; r < 4; ++r) {
1256: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
1258: DMPlexSetConeSize(rdm, newp, 6);
1259: }
1260: }
1261: /* Split faces have 4 edges and the same cells as the parent */
1262: for (f = fStart; f < fEnd; ++f) {
1263: for (r = 0; r < 3; ++r) {
1264: const PetscInt newp = fStartNew + (f - fStart)*3 + r;
1265: PetscInt size;
1267: DMPlexSetConeSize(rdm, newp, 4);
1268: DMPlexGetSupportSize(dm, f, &size);
1269: DMPlexSetSupportSize(rdm, newp, size);
1270: }
1271: }
1272: /* Interior cell faces have 4 edges and 2 cells */
1273: for (c = cStart; c < cEnd; ++c) {
1274: for (r = 0; r < 6; ++r) {
1275: const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r;
1277: DMPlexSetConeSize(rdm, newp, 4);
1278: DMPlexSetSupportSize(rdm, newp, 2);
1279: }
1280: }
1281: /* Split edges have 2 vertices and the same faces */
1282: for (e = eStart; e < eEnd; ++e) {
1283: for (r = 0; r < 2; ++r) {
1284: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1285: PetscInt size;
1287: DMPlexSetConeSize(rdm, newp, 2);
1288: DMPlexGetSupportSize(dm, e, &size);
1289: DMPlexSetSupportSize(rdm, newp, size);
1290: }
1291: }
1292: /* Face edges have 2 vertices and 2 + cell faces supports */
1293: for (f = fStart; f < fEnd; ++f) {
1294: for (r = 0; r < 3; ++r) {
1295: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
1296: PetscInt size;
1298: DMPlexSetConeSize(rdm, newp, 2);
1299: DMPlexGetSupportSize(dm, f, &size);
1300: DMPlexSetSupportSize(rdm, newp, 2+size);
1301: }
1302: }
1303: /* Interior cell edges have 2 vertices and 3 faces */
1304: for (c = cStart; c < cEnd; ++c) {
1305: for (r = 0; r < 4; ++r) {
1306: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
1308: DMPlexSetConeSize(rdm, newp, 2);
1309: DMPlexSetSupportSize(rdm, newp, 3);
1310: }
1311: }
1312: /* Old vertices have identical supports */
1313: for (v = vStart; v < vEnd; ++v) {
1314: const PetscInt newp = vStartNew + (v - vStart);
1315: PetscInt size;
1317: DMPlexGetSupportSize(dm, v, &size);
1318: DMPlexSetSupportSize(rdm, newp, size);
1319: }
1320: /* Edge vertices have 2 + faces supports */
1321: for (e = eStart; e < eEnd; ++e) {
1322: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1323: PetscInt size;
1325: DMPlexGetSupportSize(dm, e, &size);
1326: DMPlexSetSupportSize(rdm, newp, 2 + size);
1327: }
1328: /* Face vertices have 3 + cells supports */
1329: for (f = fStart; f < fEnd; ++f) {
1330: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
1331: PetscInt size;
1333: DMPlexGetSupportSize(dm, f, &size);
1334: DMPlexSetSupportSize(rdm, newp, 3 + size);
1335: }
1336: /* Interior cell vertices have 4 supports */
1337: for (c = cStart; c < cEnd; ++c) {
1338: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart;
1340: DMPlexSetSupportSize(rdm, newp, 4);
1341: }
1342: break;
1343: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
1344: /* the mesh is no longer hybrid */
1345: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1346: cMax = PetscMin(cEnd, cMax);
1347: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
1348: fMax = PetscMin(fEnd, fMax);
1349: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
1350: eMax = PetscMin(eEnd, eMax);
1351: /* All cells have 6 faces */
1352: for (c = cStart; c < cMax; ++c) {
1353: for (r = 0; r < 4; ++r) {
1354: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
1356: DMPlexSetConeSize(rdm, newp, 6);
1357: }
1358: }
1359: for (c = cMax; c < cEnd; ++c) {
1360: for (r = 0; r < 3; ++r) {
1361: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + r;
1363: DMPlexSetConeSize(rdm, newp, 6);
1364: }
1365: }
1366: /* Interior split faces have 4 edges and the same cells as the parent */
1367: for (f = fStart; f < fMax; ++f) {
1368: for (r = 0; r < 3; ++r) {
1369: const PetscInt newp = fStartNew + (f - fStart)*3 + r;
1370: PetscInt size;
1372: DMPlexSetConeSize(rdm, newp, 4);
1373: DMPlexGetSupportSize(dm, f, &size);
1374: DMPlexSetSupportSize(rdm, newp, size);
1375: }
1376: }
1377: /* Interior cell faces have 4 edges and 2 cells */
1378: for (c = cStart; c < cMax; ++c) {
1379: for (r = 0; r < 6; ++r) {
1380: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + r;
1382: DMPlexSetConeSize(rdm, newp, 4);
1383: DMPlexSetSupportSize(rdm, newp, 2);
1384: }
1385: }
1386: /* Hybrid split faces have 4 edges and the same cells as the parent */
1387: for (f = fMax; f < fEnd; ++f) {
1388: for (r = 0; r < 2; ++r) {
1389: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2 + r;
1390: PetscInt size;
1392: DMPlexSetConeSize(rdm, newp, 4);
1393: DMPlexGetSupportSize(dm, f, &size);
1394: DMPlexSetSupportSize(rdm, newp, size);
1395: }
1396: }
1397: /* Hybrid cell faces have 4 edges and 2 cells */
1398: for (c = cMax; c < cEnd; ++c) {
1399: for (r = 0; r < 3; ++r) {
1400: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
1402: DMPlexSetConeSize(rdm, newp, 4);
1403: DMPlexSetSupportSize(rdm, newp, 2);
1404: }
1405: }
1406: /* Interior split edges have 2 vertices and the same faces */
1407: for (e = eStart; e < eMax; ++e) {
1408: for (r = 0; r < 2; ++r) {
1409: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1410: PetscInt size;
1412: DMPlexSetConeSize(rdm, newp, 2);
1413: DMPlexGetSupportSize(dm, e, &size);
1414: DMPlexSetSupportSize(rdm, newp, size);
1415: }
1416: }
1417: /* Interior face edges have 2 vertices and 2 + cell faces supports */
1418: for (f = fStart; f < fMax; ++f) {
1419: for (r = 0; r < 3; ++r) {
1420: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
1421: PetscInt size;
1423: DMPlexSetConeSize(rdm, newp, 2);
1424: DMPlexGetSupportSize(dm, f, &size);
1425: DMPlexSetSupportSize(rdm, newp, 2+size);
1426: }
1427: }
1428: /* Interior cell edges have 2 vertices and 3 faces */
1429: for (c = cStart; c < cMax; ++c) {
1430: for (r = 0; r < 4; ++r) {
1431: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r;
1433: DMPlexSetConeSize(rdm, newp, 2);
1434: DMPlexSetSupportSize(rdm, newp, 3);
1435: }
1436: }
1437: /* Hybrid edges have 2 vertices and the same faces */
1438: for (e = eMax; e < eEnd; ++e) {
1439: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax);
1440: PetscInt size;
1442: DMPlexSetConeSize(rdm, newp, 2);
1443: DMPlexGetSupportSize(dm, e, &size);
1444: DMPlexSetSupportSize(rdm, newp, size);
1445: }
1446: /* Hybrid face edges have 2 vertices and 2+cells faces */
1447: for (f = fMax; f < fEnd; ++f) {
1448: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax);
1449: PetscInt size;
1451: DMPlexSetConeSize(rdm, newp, 2);
1452: DMPlexGetSupportSize(dm, f, &size);
1453: DMPlexSetSupportSize(rdm, newp, 2+size);
1454: }
1455: /* Hybrid cell edges have 2 vertices and 3 faces */
1456: for (c = cMax; c < cEnd; ++c) {
1457: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
1459: DMPlexSetConeSize(rdm, newp, 2);
1460: DMPlexSetSupportSize(rdm, newp, 3);
1461: }
1462: /* Old vertices have identical supports */
1463: for (v = vStart; v < vEnd; ++v) {
1464: const PetscInt newp = vStartNew + (v - vStart);
1465: PetscInt size;
1467: DMPlexGetSupportSize(dm, v, &size);
1468: DMPlexSetSupportSize(rdm, newp, size);
1469: }
1470: /* Interior edge vertices have 2 + faces supports */
1471: for (e = eStart; e < eMax; ++e) {
1472: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1473: PetscInt size;
1475: DMPlexGetSupportSize(dm, e, &size);
1476: DMPlexSetSupportSize(rdm, newp, 2 + size);
1477: }
1478: /* Interior face vertices have 3 + cells supports */
1479: for (f = fStart; f < fMax; ++f) {
1480: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart;
1481: PetscInt size;
1483: DMPlexGetSupportSize(dm, f, &size);
1484: DMPlexSetSupportSize(rdm, newp, 3 + size);
1485: }
1486: /* Interior cell vertices have 4 supports */
1487: for (c = cStart; c < cMax; ++c) {
1488: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart;
1490: DMPlexSetSupportSize(rdm, newp, 4);
1491: }
1492: break;
1493: case REFINER_HEX_3D:
1494: /* All cells have 6 faces */
1495: for (c = cStart; c < cEnd; ++c) {
1496: for (r = 0; r < 8; ++r) {
1497: const PetscInt newp = (c - cStart)*8 + r;
1499: DMPlexSetConeSize(rdm, newp, 6);
1500: }
1501: }
1502: /* Split faces have 4 edges and the same cells as the parent */
1503: for (f = fStart; f < fEnd; ++f) {
1504: for (r = 0; r < 4; ++r) {
1505: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
1506: PetscInt size;
1508: DMPlexSetConeSize(rdm, newp, 4);
1509: DMPlexGetSupportSize(dm, f, &size);
1510: DMPlexSetSupportSize(rdm, newp, size);
1511: }
1512: }
1513: /* Interior faces have 4 edges and 2 cells */
1514: for (c = cStart; c < cEnd; ++c) {
1515: for (r = 0; r < 12; ++r) {
1516: const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
1518: DMPlexSetConeSize(rdm, newp, 4);
1519: DMPlexSetSupportSize(rdm, newp, 2);
1520: }
1521: }
1522: /* Split edges have 2 vertices and the same faces as the parent */
1523: for (e = eStart; e < eEnd; ++e) {
1524: for (r = 0; r < 2; ++r) {
1525: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1526: PetscInt size;
1528: DMPlexSetConeSize(rdm, newp, 2);
1529: DMPlexGetSupportSize(dm, e, &size);
1530: DMPlexSetSupportSize(rdm, newp, size);
1531: }
1532: }
1533: /* Face edges have 2 vertices and 2+cells faces */
1534: for (f = fStart; f < fEnd; ++f) {
1535: for (r = 0; r < 4; ++r) {
1536: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
1537: PetscInt size;
1539: DMPlexSetConeSize(rdm, newp, 2);
1540: DMPlexGetSupportSize(dm, f, &size);
1541: DMPlexSetSupportSize(rdm, newp, 2+size);
1542: }
1543: }
1544: /* Cell edges have 2 vertices and 4 faces */
1545: for (c = cStart; c < cEnd; ++c) {
1546: for (r = 0; r < 6; ++r) {
1547: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
1549: DMPlexSetConeSize(rdm, newp, 2);
1550: DMPlexSetSupportSize(rdm, newp, 4);
1551: }
1552: }
1553: /* Old vertices have identical supports */
1554: for (v = vStart; v < vEnd; ++v) {
1555: const PetscInt newp = vStartNew + (v - vStart);
1556: PetscInt size;
1558: DMPlexGetSupportSize(dm, v, &size);
1559: DMPlexSetSupportSize(rdm, newp, size);
1560: }
1561: /* Edge vertices have 2 + faces supports */
1562: for (e = eStart; e < eEnd; ++e) {
1563: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1564: PetscInt size;
1566: DMPlexGetSupportSize(dm, e, &size);
1567: DMPlexSetSupportSize(rdm, newp, 2 + size);
1568: }
1569: /* Face vertices have 4 + cells supports */
1570: for (f = fStart; f < fEnd; ++f) {
1571: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
1572: PetscInt size;
1574: DMPlexGetSupportSize(dm, f, &size);
1575: DMPlexSetSupportSize(rdm, newp, 4 + size);
1576: }
1577: /* Cell vertices have 6 supports */
1578: for (c = cStart; c < cEnd; ++c) {
1579: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
1581: DMPlexSetSupportSize(rdm, newp, 6);
1582: }
1583: break;
1584: case REFINER_HYBRID_HEX_3D:
1585: DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
1586: eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);
1587: /* Interior cells have 6 faces */
1588: for (c = cStart; c < cMax; ++c) {
1589: for (r = 0; r < 8; ++r) {
1590: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
1592: DMPlexSetConeSize(rdm, newp, 6);
1593: }
1594: }
1595: /* Hybrid cells have 6 faces */
1596: for (c = cMax; c < cEnd; ++c) {
1597: for (r = 0; r < 4; ++r) {
1598: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
1600: DMPlexSetConeSize(rdm, newp, 6);
1601: }
1602: }
1603: /* Interior split faces have 4 edges and the same cells as the parent */
1604: for (f = fStart; f < fMax; ++f) {
1605: for (r = 0; r < 4; ++r) {
1606: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
1607: PetscInt size;
1609: DMPlexSetConeSize(rdm, newp, 4);
1610: DMPlexGetSupportSize(dm, f, &size);
1611: DMPlexSetSupportSize(rdm, newp, size);
1612: }
1613: }
1614: /* Interior cell faces have 4 edges and 2 cells */
1615: for (c = cStart; c < cMax; ++c) {
1616: for (r = 0; r < 12; ++r) {
1617: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
1619: DMPlexSetConeSize(rdm, newp, 4);
1620: DMPlexSetSupportSize(rdm, newp, 2);
1621: }
1622: }
1623: /* Hybrid split faces have 4 edges and the same cells as the parent */
1624: for (f = fMax; f < fEnd; ++f) {
1625: for (r = 0; r < 2; ++r) {
1626: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
1627: PetscInt size;
1629: DMPlexSetConeSize(rdm, newp, 4);
1630: DMPlexGetSupportSize(dm, f, &size);
1631: DMPlexSetSupportSize(rdm, newp, size);
1632: }
1633: }
1634: /* Hybrid cells faces have 4 edges and 2 cells */
1635: for (c = cMax; c < cEnd; ++c) {
1636: for (r = 0; r < 4; ++r) {
1637: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
1639: DMPlexSetConeSize(rdm, newp, 4);
1640: DMPlexSetSupportSize(rdm, newp, 2);
1641: }
1642: }
1643: /* Interior split edges have 2 vertices and the same faces as the parent */
1644: for (e = eStart; e < eMax; ++e) {
1645: for (r = 0; r < 2; ++r) {
1646: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1647: PetscInt size;
1649: DMPlexSetConeSize(rdm, newp, 2);
1650: DMPlexGetSupportSize(dm, e, &size);
1651: DMPlexSetSupportSize(rdm, newp, size);
1652: }
1653: }
1654: /* Interior face edges have 2 vertices and 2+cells faces */
1655: for (f = fStart; f < fMax; ++f) {
1656: for (r = 0; r < 4; ++r) {
1657: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
1658: PetscInt size;
1660: DMPlexSetConeSize(rdm, newp, 2);
1661: DMPlexGetSupportSize(dm, f, &size);
1662: DMPlexSetSupportSize(rdm, newp, 2+size);
1663: }
1664: }
1665: /* Interior cell edges have 2 vertices and 4 faces */
1666: for (c = cStart; c < cMax; ++c) {
1667: for (r = 0; r < 6; ++r) {
1668: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
1670: DMPlexSetConeSize(rdm, newp, 2);
1671: DMPlexSetSupportSize(rdm, newp, 4);
1672: }
1673: }
1674: /* Hybrid edges have 2 vertices and the same faces */
1675: for (e = eMax; e < eEnd; ++e) {
1676: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
1677: PetscInt size;
1679: DMPlexSetConeSize(rdm, newp, 2);
1680: DMPlexGetSupportSize(dm, e, &size);
1681: DMPlexSetSupportSize(rdm, newp, size);
1682: }
1683: /* Hybrid face edges have 2 vertices and 2+cells faces */
1684: for (f = fMax; f < fEnd; ++f) {
1685: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
1686: PetscInt size;
1688: DMPlexSetConeSize(rdm, newp, 2);
1689: DMPlexGetSupportSize(dm, f, &size);
1690: DMPlexSetSupportSize(rdm, newp, 2+size);
1691: }
1692: /* Hybrid cell edges have 2 vertices and 4 faces */
1693: for (c = cMax; c < cEnd; ++c) {
1694: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
1696: DMPlexSetConeSize(rdm, newp, 2);
1697: DMPlexSetSupportSize(rdm, newp, 4);
1698: }
1699: /* Interior vertices have identical supports */
1700: for (v = vStart; v < vEnd; ++v) {
1701: const PetscInt newp = vStartNew + (v - vStart);
1702: PetscInt size;
1704: DMPlexGetSupportSize(dm, v, &size);
1705: DMPlexSetSupportSize(rdm, newp, size);
1706: }
1707: /* Interior edge vertices have 2 + faces supports */
1708: for (e = eStart; e < eMax; ++e) {
1709: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1710: PetscInt size;
1712: DMPlexGetSupportSize(dm, e, &size);
1713: DMPlexSetSupportSize(rdm, newp, 2 + size);
1714: }
1715: /* Interior face vertices have 4 + cells supports */
1716: for (f = fStart; f < fMax; ++f) {
1717: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
1718: PetscInt size;
1720: DMPlexGetSupportSize(dm, f, &size);
1721: DMPlexSetSupportSize(rdm, newp, 4 + size);
1722: }
1723: /* Interior cell vertices have 6 supports */
1724: for (c = cStart; c < cMax; ++c) {
1725: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
1727: DMPlexSetSupportSize(rdm, newp, 6);
1728: }
1729: break;
1730: default:
1731: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
1732: }
1733: return(0);
1734: }
1736: static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
1737: {
1738: const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
1739: PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
1740: PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
1741: PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r;
1742: #if defined(PETSC_USE_DEBUG)
1743: PetscInt p;
1744: #endif
1745: PetscErrorCode ierr;
1748: if (!refiner) return(0);
1749: DMPlexGetDepth(dm, &depth);
1750: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
1751: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
1752: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
1753: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
1754: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
1755: GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);
1756: GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);
1757: switch (refiner) {
1758: case REFINER_SIMPLEX_1D:
1759: /* Max support size of refined mesh is 2 */
1760: PetscMalloc1(2, &supportRef);
1761: /* All cells have 2 vertices */
1762: for (c = cStart; c < cEnd; ++c) {
1763: const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart);
1765: for (r = 0; r < 2; ++r) {
1766: const PetscInt newp = cStartNew + (c - cStart)*2 + r;
1767: const PetscInt *cone;
1768: PetscInt coneNew[2];
1770: DMPlexGetCone(dm, c, &cone);
1771: coneNew[0] = vStartNew + (cone[0] - vStart);
1772: coneNew[1] = vStartNew + (cone[1] - vStart);
1773: coneNew[(r+1)%2] = newv;
1774: DMPlexSetCone(rdm, newp, coneNew);
1775: #if defined(PETSC_USE_DEBUG)
1776: if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp, cStartNew, cEndNew);
1777: for (p = 0; p < 2; ++p) {
1778: 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);
1779: }
1780: #endif
1781: }
1782: }
1783: /* Old vertices have identical supports */
1784: for (v = vStart; v < vEnd; ++v) {
1785: const PetscInt newp = vStartNew + (v - vStart);
1786: const PetscInt *support, *cone;
1787: PetscInt size, s;
1789: DMPlexGetSupportSize(dm, v, &size);
1790: DMPlexGetSupport(dm, v, &support);
1791: for (s = 0; s < size; ++s) {
1792: PetscInt r = 0;
1794: DMPlexGetCone(dm, support[s], &cone);
1795: if (cone[1] == v) r = 1;
1796: supportRef[s] = cStartNew + (support[s] - cStart)*2 + r;
1797: }
1798: DMPlexSetSupport(rdm, newp, supportRef);
1799: #if defined(PETSC_USE_DEBUG)
1800: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
1801: for (p = 0; p < size; ++p) {
1802: 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);
1803: }
1804: #endif
1805: }
1806: /* Cell vertices have support of 2 cells */
1807: for (c = cStart; c < cEnd; ++c) {
1808: const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart);
1810: supportRef[0] = cStartNew + (c - cStart)*2 + 0;
1811: supportRef[1] = cStartNew + (c - cStart)*2 + 1;
1812: DMPlexSetSupport(rdm, newp, supportRef);
1813: #if defined(PETSC_USE_DEBUG)
1814: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
1815: for (p = 0; p < 2; ++p) {
1816: 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);
1817: }
1818: #endif
1819: }
1820: PetscFree(supportRef);
1821: break;
1822: case REFINER_SIMPLEX_2D:
1823: /*
1824: 2
1825: |\
1826: | \
1827: | \
1828: | \
1829: | C \
1830: | \
1831: | \
1832: 2---1---1
1833: |\ D / \
1834: | 2 0 \
1835: |A \ / B \
1836: 0---0-------1
1837: */
1838: /* All cells have 3 faces */
1839: for (c = cStart; c < cEnd; ++c) {
1840: const PetscInt newp = cStartNew + (c - cStart)*4;
1841: const PetscInt *cone, *ornt;
1842: PetscInt coneNew[3], orntNew[3];
1844: DMPlexGetCone(dm, c, &cone);
1845: DMPlexGetConeOrientation(dm, c, &ornt);
1846: /* A triangle */
1847: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1848: orntNew[0] = ornt[0];
1849: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1850: orntNew[1] = -2;
1851: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1852: orntNew[2] = ornt[2];
1853: DMPlexSetCone(rdm, newp+0, coneNew);
1854: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
1855: #if defined(PETSC_USE_DEBUG)
1856: 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);
1857: for (p = 0; p < 3; ++p) {
1858: 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);
1859: }
1860: #endif
1861: /* B triangle */
1862: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1863: orntNew[0] = ornt[0];
1864: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1865: orntNew[1] = ornt[1];
1866: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1867: orntNew[2] = -2;
1868: DMPlexSetCone(rdm, newp+1, coneNew);
1869: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
1870: #if defined(PETSC_USE_DEBUG)
1871: 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);
1872: for (p = 0; p < 3; ++p) {
1873: 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);
1874: }
1875: #endif
1876: /* C triangle */
1877: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1878: orntNew[0] = -2;
1879: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1880: orntNew[1] = ornt[1];
1881: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1882: orntNew[2] = ornt[2];
1883: DMPlexSetCone(rdm, newp+2, coneNew);
1884: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
1885: #if defined(PETSC_USE_DEBUG)
1886: 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);
1887: for (p = 0; p < 3; ++p) {
1888: 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);
1889: }
1890: #endif
1891: /* D triangle */
1892: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1893: orntNew[0] = 0;
1894: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1895: orntNew[1] = 0;
1896: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1897: orntNew[2] = 0;
1898: DMPlexSetCone(rdm, newp+3, coneNew);
1899: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
1900: #if defined(PETSC_USE_DEBUG)
1901: 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);
1902: for (p = 0; p < 3; ++p) {
1903: 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);
1904: }
1905: #endif
1906: }
1907: /* Split faces have 2 vertices and the same cells as the parent */
1908: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
1909: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
1910: for (f = fStart; f < fEnd; ++f) {
1911: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1913: for (r = 0; r < 2; ++r) {
1914: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
1915: const PetscInt *cone, *ornt, *support;
1916: PetscInt coneNew[2], coneSize, c, supportSize, s;
1918: DMPlexGetCone(dm, f, &cone);
1919: coneNew[0] = vStartNew + (cone[0] - vStart);
1920: coneNew[1] = vStartNew + (cone[1] - vStart);
1921: coneNew[(r+1)%2] = newv;
1922: DMPlexSetCone(rdm, newp, coneNew);
1923: #if defined(PETSC_USE_DEBUG)
1924: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1925: for (p = 0; p < 2; ++p) {
1926: 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);
1927: }
1928: #endif
1929: DMPlexGetSupportSize(dm, f, &supportSize);
1930: DMPlexGetSupport(dm, f, &support);
1931: for (s = 0; s < supportSize; ++s) {
1932: DMPlexGetConeSize(dm, support[s], &coneSize);
1933: DMPlexGetCone(dm, support[s], &cone);
1934: DMPlexGetConeOrientation(dm, support[s], &ornt);
1935: for (c = 0; c < coneSize; ++c) {
1936: if (cone[c] == f) break;
1937: }
1938: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
1939: }
1940: DMPlexSetSupport(rdm, newp, supportRef);
1941: #if defined(PETSC_USE_DEBUG)
1942: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1943: for (p = 0; p < supportSize; ++p) {
1944: 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);
1945: }
1946: #endif
1947: }
1948: }
1949: /* Interior faces have 2 vertices and 2 cells */
1950: for (c = cStart; c < cEnd; ++c) {
1951: const PetscInt *cone;
1953: DMPlexGetCone(dm, c, &cone);
1954: for (r = 0; r < 3; ++r) {
1955: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
1956: PetscInt coneNew[2];
1957: PetscInt supportNew[2];
1959: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1960: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
1961: DMPlexSetCone(rdm, newp, coneNew);
1962: #if defined(PETSC_USE_DEBUG)
1963: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1964: for (p = 0; p < 2; ++p) {
1965: 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);
1966: }
1967: #endif
1968: supportNew[0] = (c - cStart)*4 + (r+1)%3;
1969: supportNew[1] = (c - cStart)*4 + 3;
1970: DMPlexSetSupport(rdm, newp, supportNew);
1971: #if defined(PETSC_USE_DEBUG)
1972: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1973: for (p = 0; p < 2; ++p) {
1974: 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);
1975: }
1976: #endif
1977: }
1978: }
1979: /* Old vertices have identical supports */
1980: for (v = vStart; v < vEnd; ++v) {
1981: const PetscInt newp = vStartNew + (v - vStart);
1982: const PetscInt *support, *cone;
1983: PetscInt size, s;
1985: DMPlexGetSupportSize(dm, v, &size);
1986: DMPlexGetSupport(dm, v, &support);
1987: for (s = 0; s < size; ++s) {
1988: PetscInt r = 0;
1990: DMPlexGetCone(dm, support[s], &cone);
1991: if (cone[1] == v) r = 1;
1992: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
1993: }
1994: DMPlexSetSupport(rdm, newp, supportRef);
1995: #if defined(PETSC_USE_DEBUG)
1996: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
1997: for (p = 0; p < size; ++p) {
1998: 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);
1999: }
2000: #endif
2001: }
2002: /* Face vertices have 2 + cells*2 supports */
2003: for (f = fStart; f < fEnd; ++f) {
2004: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2005: const PetscInt *cone, *support;
2006: PetscInt size, s;
2008: DMPlexGetSupportSize(dm, f, &size);
2009: DMPlexGetSupport(dm, f, &support);
2010: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2011: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2012: for (s = 0; s < size; ++s) {
2013: PetscInt r = 0;
2015: DMPlexGetCone(dm, support[s], &cone);
2016: if (cone[1] == f) r = 1;
2017: else if (cone[2] == f) r = 2;
2018: supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
2019: supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
2020: }
2021: DMPlexSetSupport(rdm, newp, supportRef);
2022: #if defined(PETSC_USE_DEBUG)
2023: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2024: for (p = 0; p < 2+size*2; ++p) {
2025: 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);
2026: }
2027: #endif
2028: }
2029: PetscFree(supportRef);
2030: break;
2031: case REFINER_SIMPLEX_TO_HEX_2D:
2032: /*
2033: 2
2034: |\
2035: | \
2036: | \
2037: | \
2038: | C \
2039: | \
2040: 2 1
2041: |\ / \
2042: | 2 1 \
2043: | \/ \
2044: | | \
2045: |A | B \
2046: | 0 \
2047: | | \
2048: 0---0----------1
2049: */
2050: /* All cells have 4 faces */
2051: for (c = cStart; c < cEnd; ++c) {
2052: const PetscInt newp = cStartNew + (c - cStart)*3;
2053: const PetscInt *cone, *ornt;
2054: PetscInt coneNew[4], orntNew[4];
2056: DMPlexGetCone(dm, c, &cone);
2057: DMPlexGetConeOrientation(dm, c, &ornt);
2058: /* A quad */
2059: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2060: orntNew[0] = ornt[0];
2061: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2062: orntNew[1] = 0;
2063: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2064: orntNew[2] = -2;
2065: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2066: orntNew[3] = ornt[2];
2067: DMPlexSetCone(rdm, newp+0, coneNew);
2068: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2069: #if defined(PETSC_USE_DEBUG)
2070: 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);
2071: for (p = 0; p < 4; ++p) {
2072: 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);
2073: }
2074: #endif
2075: /* B quad */
2076: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2077: orntNew[0] = ornt[0];
2078: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2079: orntNew[1] = ornt[1];
2080: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2081: orntNew[2] = 0;
2082: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2083: orntNew[3] = -2;
2084: DMPlexSetCone(rdm, newp+1, coneNew);
2085: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2086: #if defined(PETSC_USE_DEBUG)
2087: 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);
2088: for (p = 0; p < 4; ++p) {
2089: 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);
2090: }
2091: #endif
2092: /* C quad */
2093: coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2094: orntNew[0] = ornt[1];
2095: coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2096: orntNew[1] = ornt[2];
2097: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2098: orntNew[2] = 0;
2099: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2100: orntNew[3] = -2;
2101: DMPlexSetCone(rdm, newp+2, coneNew);
2102: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2103: #if defined(PETSC_USE_DEBUG)
2104: 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);
2105: for (p = 0; p < 4; ++p) {
2106: 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);
2107: }
2108: #endif
2109: }
2110: /* Split faces have 2 vertices and the same cells as the parent */
2111: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2112: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2113: for (f = fStart; f < fEnd; ++f) {
2114: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2116: for (r = 0; r < 2; ++r) {
2117: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2118: const PetscInt *cone, *ornt, *support;
2119: PetscInt coneNew[2], coneSize, c, supportSize, s;
2121: DMPlexGetCone(dm, f, &cone);
2122: coneNew[0] = vStartNew + (cone[0] - vStart);
2123: coneNew[1] = vStartNew + (cone[1] - vStart);
2124: coneNew[(r+1)%2] = newv;
2125: DMPlexSetCone(rdm, newp, coneNew);
2126: #if defined(PETSC_USE_DEBUG)
2127: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2128: for (p = 0; p < 2; ++p) {
2129: 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);
2130: }
2131: #endif
2132: DMPlexGetSupportSize(dm, f, &supportSize);
2133: DMPlexGetSupport(dm, f, &support);
2134: for (s = 0; s < supportSize; ++s) {
2135: DMPlexGetConeSize(dm, support[s], &coneSize);
2136: DMPlexGetCone(dm, support[s], &cone);
2137: DMPlexGetConeOrientation(dm, support[s], &ornt);
2138: for (c = 0; c < coneSize; ++c) {
2139: if (cone[c] == f) break;
2140: }
2141: supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
2142: }
2143: DMPlexSetSupport(rdm, newp, supportRef);
2144: #if defined(PETSC_USE_DEBUG)
2145: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2146: for (p = 0; p < supportSize; ++p) {
2147: 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);
2148: }
2149: #endif
2150: }
2151: }
2152: /* Interior faces have 2 vertices and 2 cells */
2153: for (c = cStart; c < cEnd; ++c) {
2154: const PetscInt *cone;
2156: DMPlexGetCone(dm, c, &cone);
2157: for (r = 0; r < 3; ++r) {
2158: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
2159: PetscInt coneNew[2];
2160: PetscInt supportNew[2];
2162: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2163: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2164: DMPlexSetCone(rdm, newp, coneNew);
2165: #if defined(PETSC_USE_DEBUG)
2166: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2167: for (p = 0; p < 2; ++p) {
2168: 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);
2169: }
2170: #endif
2171: supportNew[0] = (c - cStart)*3 + r%3;
2172: supportNew[1] = (c - cStart)*3 + (r+1)%3;
2173: DMPlexSetSupport(rdm, newp, supportNew);
2174: #if defined(PETSC_USE_DEBUG)
2175: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2176: for (p = 0; p < 2; ++p) {
2177: 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);
2178: }
2179: #endif
2180: }
2181: }
2182: /* Old vertices have identical supports */
2183: for (v = vStart; v < vEnd; ++v) {
2184: const PetscInt newp = vStartNew + (v - vStart);
2185: const PetscInt *support, *cone;
2186: PetscInt size, s;
2188: DMPlexGetSupportSize(dm, v, &size);
2189: DMPlexGetSupport(dm, v, &support);
2190: for (s = 0; s < size; ++s) {
2191: PetscInt r = 0;
2193: DMPlexGetCone(dm, support[s], &cone);
2194: if (cone[1] == v) r = 1;
2195: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2196: }
2197: DMPlexSetSupport(rdm, newp, supportRef);
2198: #if defined(PETSC_USE_DEBUG)
2199: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2200: for (p = 0; p < size; ++p) {
2201: 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);
2202: }
2203: #endif
2204: }
2205: /* Split-face vertices have cells + 2 supports */
2206: for (f = fStart; f < fEnd; ++f) {
2207: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2208: const PetscInt *cone, *support;
2209: PetscInt size, s;
2211: DMPlexGetSupportSize(dm, f, &size);
2212: DMPlexGetSupport(dm, f, &support);
2213: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2214: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2215: for (s = 0; s < size; ++s) {
2216: PetscInt r = 0;
2218: DMPlexGetCone(dm, support[s], &cone);
2219: if (cone[1] == f) r = 1;
2220: else if (cone[2] == f) r = 2;
2221: supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
2222: }
2223: DMPlexSetSupport(rdm, newp, supportRef);
2224: #if defined(PETSC_USE_DEBUG)
2225: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2226: for (p = 0; p < 2+size; ++p) {
2227: 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);
2228: }
2229: #endif
2230: }
2231: /* Interior vertices have 3 supports */
2232: for (c = cStart; c < cEnd; ++c) {
2233: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
2235: supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2236: supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2237: supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2238: DMPlexSetSupport(rdm, newp, supportRef);
2239: }
2240: PetscFree(supportRef);
2241: break;
2242: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
2243: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2244: cMax = PetscMin(cEnd, cMax);
2245: for (c = cStart; c < cMax; ++c) {
2246: const PetscInt newp = cStartNew + (c - cStart)*3;
2247: const PetscInt *cone, *ornt;
2248: PetscInt coneNew[4], orntNew[4];
2250: DMPlexGetCone(dm, c, &cone);
2251: DMPlexGetConeOrientation(dm, c, &ornt);
2252: /* A quad */
2253: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2254: orntNew[0] = ornt[0];
2255: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2256: orntNew[1] = 0;
2257: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2258: orntNew[2] = -2;
2259: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2260: orntNew[3] = ornt[2];
2261: DMPlexSetCone(rdm, newp+0, coneNew);
2262: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2263: #if defined(PETSC_USE_DEBUG)
2264: 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);
2265: for (p = 0; p < 4; ++p) {
2266: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew);
2267: }
2268: #endif
2269: /* B quad */
2270: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2271: orntNew[0] = ornt[0];
2272: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2273: orntNew[1] = ornt[1];
2274: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2275: orntNew[2] = 0;
2276: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2277: orntNew[3] = -2;
2278: DMPlexSetCone(rdm, newp+1, coneNew);
2279: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2280: #if defined(PETSC_USE_DEBUG)
2281: 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);
2282: for (p = 0; p < 4; ++p) {
2283: 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);
2284: }
2285: #endif
2286: /* C quad */
2287: coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2288: orntNew[0] = ornt[1];
2289: coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2290: orntNew[1] = ornt[2];
2291: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2292: orntNew[2] = 0;
2293: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2294: orntNew[3] = -2;
2295: DMPlexSetCone(rdm, newp+2, coneNew);
2296: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2297: #if defined(PETSC_USE_DEBUG)
2298: 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);
2299: for (p = 0; p < 4; ++p) {
2300: 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);
2301: }
2302: #endif
2303: }
2304: /*
2305: 2---------1---------3
2306: | | |
2307: | D 1 C |
2308: | | |
2309: 2----2----0----3----3
2310: | | |
2311: | A 0 B |
2312: | | |
2313: 0---------0---------1
2314: */
2315: /* Parent cells are input as prisms but children are quads, since the mesh is no longer hybrid */
2316: for (c = cMax; c < cEnd; ++c) {
2317: const PetscInt newp = cStartNew + (cMax - cStart)*3 + (c - cMax)*4;
2318: const PetscInt newpt = (cMax - cStart)*3 + (c - cMax)*4;
2319: const PetscInt *cone, *ornt;
2320: PetscInt coneNew[4], orntNew[4];
2322: DMPlexGetCone(dm, c, &cone);
2323: DMPlexGetConeOrientation(dm, c, &ornt);
2324: /* A quad */
2325: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2326: orntNew[0] = ornt[0];
2327: coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 0;
2328: orntNew[1] = 0;
2329: coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 2;
2330: orntNew[2] = -2;
2331: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2332: orntNew[3] = ornt[2] < 0 ? 0 : -2;
2333: DMPlexSetCone(rdm, newp+0, coneNew);
2334: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2335: #if defined(PETSC_USE_DEBUG)
2336: 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);
2337: for (p = 0; p < 4; ++p) {
2338: 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);
2339: }
2340: #endif
2341: /* B quad */
2342: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2343: orntNew[0] = ornt[0];
2344: coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2345: orntNew[1] = ornt[3];
2346: coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 3;
2347: orntNew[2] = 0;
2348: coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 0;
2349: orntNew[3] = -2;
2350: DMPlexSetCone(rdm, newp+1, coneNew);
2351: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2352: #if defined(PETSC_USE_DEBUG)
2353: 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);
2354: for (p = 0; p < 4; ++p) {
2355: 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);
2356: }
2357: #endif
2358: /* C quad */
2359: coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 3;
2360: orntNew[0] = -2;
2361: coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
2362: orntNew[1] = ornt[3];
2363: coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2364: orntNew[2] = ornt[1] < 0 ? 0 : -2;
2365: coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 1;
2366: orntNew[3] = 0;
2367: DMPlexSetCone(rdm, newp+2, coneNew);
2368: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2369: #if defined(PETSC_USE_DEBUG)
2370: 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);
2371: for (p = 0; p < 4; ++p) {
2372: 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);
2373: }
2374: #endif
2375: /* D quad */
2376: coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 2;
2377: orntNew[0] = 0;
2378: coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 1;
2379: orntNew[1] = -2;
2380: coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2381: orntNew[2] = ornt[1] < 0 ? 0 : -2;
2382: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2383: orntNew[3] = ornt[2] < 0 ? 0 : -2;
2384: DMPlexSetCone(rdm, newp+3, coneNew);
2385: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2386: #if defined(PETSC_USE_DEBUG)
2387: 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);
2388: for (p = 0; p < 4; ++p) {
2389: 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);
2390: }
2391: #endif
2392: }
2393: /* Split faces have 2 vertices and the same cells as the parent */
2394: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2395: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2396: for (f = fStart; f < fEnd; ++f) {
2397: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2399: for (r = 0; r < 2; ++r) {
2400: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2401: const PetscInt *cone, *ornt, *support;
2402: PetscInt coneNew[2], coneSize, c, supportSize, s;
2404: DMPlexGetCone(dm, f, &cone);
2405: coneNew[0] = vStartNew + (cone[0] - vStart);
2406: coneNew[1] = vStartNew + (cone[1] - vStart);
2407: coneNew[(r+1)%2] = newv;
2408: DMPlexSetCone(rdm, newp, coneNew);
2409: #if defined(PETSC_USE_DEBUG)
2410: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2411: for (p = 0; p < 2; ++p) {
2412: 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);
2413: }
2414: #endif
2415: DMPlexGetSupportSize(dm, f, &supportSize);
2416: DMPlexGetSupport(dm, f, &support);
2417: for (s = 0; s < supportSize; ++s) {
2418: const PetscInt p2q[4][2] = { {0, 1},
2419: {3, 2},
2420: {0, 3},
2421: {1, 2} };
2423: DMPlexGetConeSize(dm, support[s], &coneSize);
2424: DMPlexGetCone(dm, support[s], &cone);
2425: DMPlexGetConeOrientation(dm, support[s], &ornt);
2426: for (c = 0; c < coneSize; ++c) {
2427: if (cone[c] == f) break;
2428: }
2429: if (coneSize == 3) supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
2430: 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]);
2431: else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize);
2432: }
2433: DMPlexSetSupport(rdm, newp, supportRef);
2434: #if defined(PETSC_USE_DEBUG)
2435: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2436: for (p = 0; p < supportSize; ++p) {
2437: 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);
2438: }
2439: #endif
2440: }
2441: }
2442: /* Interior faces have 2 vertices and 2 cells */
2443: for (c = cStart; c < cMax; ++c) {
2444: const PetscInt *cone;
2446: DMPlexGetCone(dm, c, &cone);
2447: for (r = 0; r < 3; ++r) {
2448: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
2449: PetscInt coneNew[2];
2450: PetscInt supportNew[2];
2452: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2453: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2454: DMPlexSetCone(rdm, newp, coneNew);
2455: #if defined(PETSC_USE_DEBUG)
2456: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2457: for (p = 0; p < 2; ++p) {
2458: 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);
2459: }
2460: #endif
2461: supportNew[0] = (c - cStart)*3 + r%3;
2462: supportNew[1] = (c - cStart)*3 + (r+1)%3;
2463: DMPlexSetSupport(rdm, newp, supportNew);
2464: #if defined(PETSC_USE_DEBUG)
2465: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2466: for (p = 0; p < 2; ++p) {
2467: 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);
2468: }
2469: #endif
2470: }
2471: }
2472: /* Hybrid interior faces have 2 vertices and 2 cells */
2473: for (c = cMax; c < cEnd; ++c) {
2474: const PetscInt *cone;
2475: PetscInt coneNew[2], supportNew[2];
2477: DMPlexGetCone(dm, c, &cone);
2478: for (r = 0; r < 4; ++r) {
2479: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r;
2481: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2482: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (cMax - cStart) + (c - cMax);
2483: DMPlexSetCone(rdm, newp, coneNew);
2484: #if defined(PETSC_USE_DEBUG)
2485: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2486: for (p = 0; p < 2; ++p) {
2487: 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);
2488: }
2489: #endif
2490: if (r==0) {
2491: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0;
2492: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 1;
2493: } else if (r==1) {
2494: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 2;
2495: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3;
2496: } else if (r==2) {
2497: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0;
2498: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3;
2499: } else {
2500: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 1;
2501: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 2;
2502: }
2503: DMPlexSetSupport(rdm, newp, supportNew);
2504: #if defined(PETSC_USE_DEBUG)
2505: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2506: for (p = 0; p < 2; ++p) {
2507: 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);
2508: }
2509: #endif
2510: }
2511: }
2512: /* Old vertices have identical supports */
2513: for (v = vStart; v < vEnd; ++v) {
2514: const PetscInt newp = vStartNew + (v - vStart);
2515: const PetscInt *support, *cone;
2516: PetscInt size, s;
2518: DMPlexGetSupportSize(dm, v, &size);
2519: DMPlexGetSupport(dm, v, &support);
2520: for (s = 0; s < size; ++s) {
2521: PetscInt r = 0;
2523: DMPlexGetCone(dm, support[s], &cone);
2524: if (cone[1] == v) r = 1;
2525: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2526: }
2527: DMPlexSetSupport(rdm, newp, supportRef);
2528: #if defined(PETSC_USE_DEBUG)
2529: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2530: for (p = 0; p < size; ++p) {
2531: 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);
2532: }
2533: #endif
2534: }
2535: /* Split-face vertices have cells + 2 supports */
2536: for (f = fStart; f < fEnd; ++f) {
2537: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2538: const PetscInt *cone, *support;
2539: PetscInt size, s;
2541: DMPlexGetSupportSize(dm, f, &size);
2542: DMPlexGetSupport(dm, f, &support);
2543: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2544: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2545: for (s = 0; s < size; ++s) {
2546: PetscInt r = 0, coneSize;
2548: DMPlexGetCone(dm, support[s], &cone);
2549: DMPlexGetConeSize(dm, support[s], &coneSize);
2550: if (coneSize == 3) {
2551: if (cone[1] == f) r = 1;
2552: else if (cone[2] == f) r = 2;
2553: supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
2554: } else if (coneSize == 4) {
2555: if (cone[1] == f) r = 1;
2556: else if (cone[2] == f) r = 2;
2557: else if (cone[3] == f) r = 3;
2558: supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (support[s] - cMax)*4 + r;
2559: } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize);
2560: }
2561: DMPlexSetSupport(rdm, newp, supportRef);
2562: #if defined(PETSC_USE_DEBUG)
2563: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2564: for (p = 0; p < 2+size; ++p) {
2565: 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);
2566: }
2567: #endif
2568: }
2569: /* Interior vertices have 3 supports */
2570: for (c = cStart; c < cMax; ++c) {
2571: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
2573: supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2574: supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2575: supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2576: DMPlexSetSupport(rdm, newp, supportRef);
2577: }
2578: /* Hybrid interior vertices have 4 supports */
2579: for (c = cMax; c < cEnd; ++c) {
2580: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
2582: supportRef[0] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 0;
2583: supportRef[1] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 1;
2584: supportRef[2] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 2;
2585: supportRef[3] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 3;
2586: DMPlexSetSupport(rdm, newp, supportRef);
2587: }
2588: PetscFree(supportRef);
2589: break;
2590: case REFINER_HEX_2D:
2591: /*
2592: 3---------2---------2
2593: | | |
2594: | D 2 C |
2595: | | |
2596: 3----3----0----1----1
2597: | | |
2598: | A 0 B |
2599: | | |
2600: 0---------0---------1
2601: */
2602: /* All cells have 4 faces */
2603: for (c = cStart; c < cEnd; ++c) {
2604: const PetscInt newp = (c - cStart)*4;
2605: const PetscInt *cone, *ornt;
2606: PetscInt coneNew[4], orntNew[4];
2608: DMPlexGetCone(dm, c, &cone);
2609: DMPlexGetConeOrientation(dm, c, &ornt);
2610: /* A quad */
2611: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2612: orntNew[0] = ornt[0];
2613: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0;
2614: orntNew[1] = 0;
2615: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3;
2616: orntNew[2] = -2;
2617: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
2618: orntNew[3] = ornt[3];
2619: DMPlexSetCone(rdm, newp+0, coneNew);
2620: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2621: #if defined(PETSC_USE_DEBUG)
2622: 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);
2623: for (p = 0; p < 4; ++p) {
2624: 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);
2625: }
2626: #endif
2627: /* B quad */
2628: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2629: orntNew[0] = ornt[0];
2630: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2631: orntNew[1] = ornt[1];
2632: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1;
2633: orntNew[2] = -2;
2634: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0;
2635: orntNew[3] = -2;
2636: DMPlexSetCone(rdm, newp+1, coneNew);
2637: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2638: #if defined(PETSC_USE_DEBUG)
2639: 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);
2640: for (p = 0; p < 4; ++p) {
2641: 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);
2642: }
2643: #endif
2644: /* C quad */
2645: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1;
2646: orntNew[0] = 0;
2647: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2648: orntNew[1] = ornt[1];
2649: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2650: orntNew[2] = ornt[2];
2651: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2;
2652: orntNew[3] = -2;
2653: DMPlexSetCone(rdm, newp+2, coneNew);
2654: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2655: #if defined(PETSC_USE_DEBUG)
2656: 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);
2657: for (p = 0; p < 4; ++p) {
2658: 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);
2659: }
2660: #endif
2661: /* D quad */
2662: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3;
2663: orntNew[0] = 0;
2664: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2;
2665: orntNew[1] = 0;
2666: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2667: orntNew[2] = ornt[2];
2668: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2669: orntNew[3] = ornt[3];
2670: DMPlexSetCone(rdm, newp+3, coneNew);
2671: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2672: #if defined(PETSC_USE_DEBUG)
2673: 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);
2674: for (p = 0; p < 4; ++p) {
2675: 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);
2676: }
2677: #endif
2678: }
2679: /* Split faces have 2 vertices and the same cells as the parent */
2680: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2681: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2682: for (f = fStart; f < fEnd; ++f) {
2683: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2685: for (r = 0; r < 2; ++r) {
2686: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2687: const PetscInt *cone, *ornt, *support;
2688: PetscInt coneNew[2], coneSize, c, supportSize, s;
2690: DMPlexGetCone(dm, f, &cone);
2691: coneNew[0] = vStartNew + (cone[0] - vStart);
2692: coneNew[1] = vStartNew + (cone[1] - vStart);
2693: coneNew[(r+1)%2] = newv;
2694: DMPlexSetCone(rdm, newp, coneNew);
2695: #if defined(PETSC_USE_DEBUG)
2696: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2697: for (p = 0; p < 2; ++p) {
2698: 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);
2699: }
2700: #endif
2701: DMPlexGetSupportSize(dm, f, &supportSize);
2702: DMPlexGetSupport(dm, f, &support);
2703: for (s = 0; s < supportSize; ++s) {
2704: DMPlexGetConeSize(dm, support[s], &coneSize);
2705: DMPlexGetCone(dm, support[s], &cone);
2706: DMPlexGetConeOrientation(dm, support[s], &ornt);
2707: for (c = 0; c < coneSize; ++c) {
2708: if (cone[c] == f) break;
2709: }
2710: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2711: }
2712: DMPlexSetSupport(rdm, newp, supportRef);
2713: #if defined(PETSC_USE_DEBUG)
2714: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2715: for (p = 0; p < supportSize; ++p) {
2716: 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);
2717: }
2718: #endif
2719: }
2720: }
2721: /* Interior faces have 2 vertices and 2 cells */
2722: for (c = cStart; c < cEnd; ++c) {
2723: const PetscInt *cone;
2724: PetscInt coneNew[2], supportNew[2];
2726: DMPlexGetCone(dm, c, &cone);
2727: for (r = 0; r < 4; ++r) {
2728: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
2730: if (r==1 || r==2) {
2731: coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2732: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2733: } else {
2734: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2735: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2736: }
2737: DMPlexSetCone(rdm, newp, coneNew);
2738: #if defined(PETSC_USE_DEBUG)
2739: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2740: for (p = 0; p < 2; ++p) {
2741: 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);
2742: }
2743: #endif
2744: supportNew[0] = (c - cStart)*4 + r;
2745: supportNew[1] = (c - cStart)*4 + (r+1)%4;
2746: DMPlexSetSupport(rdm, newp, supportNew);
2747: #if defined(PETSC_USE_DEBUG)
2748: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2749: for (p = 0; p < 2; ++p) {
2750: 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);
2751: }
2752: #endif
2753: }
2754: }
2755: /* Old vertices have identical supports */
2756: for (v = vStart; v < vEnd; ++v) {
2757: const PetscInt newp = vStartNew + (v - vStart);
2758: const PetscInt *support, *cone;
2759: PetscInt size, s;
2761: DMPlexGetSupportSize(dm, v, &size);
2762: DMPlexGetSupport(dm, v, &support);
2763: for (s = 0; s < size; ++s) {
2764: PetscInt r = 0;
2766: DMPlexGetCone(dm, support[s], &cone);
2767: if (cone[1] == v) r = 1;
2768: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2769: }
2770: DMPlexSetSupport(rdm, newp, supportRef);
2771: #if defined(PETSC_USE_DEBUG)
2772: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2773: for (p = 0; p < size; ++p) {
2774: 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);
2775: }
2776: #endif
2777: }
2778: /* Face vertices have 2 + cells supports */
2779: for (f = fStart; f < fEnd; ++f) {
2780: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2781: const PetscInt *cone, *support;
2782: PetscInt size, s;
2784: DMPlexGetSupportSize(dm, f, &size);
2785: DMPlexGetSupport(dm, f, &support);
2786: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2787: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2788: for (s = 0; s < size; ++s) {
2789: PetscInt r = 0;
2791: DMPlexGetCone(dm, support[s], &cone);
2792: if (cone[1] == f) r = 1;
2793: else if (cone[2] == f) r = 2;
2794: else if (cone[3] == f) r = 3;
2795: supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
2796: }
2797: DMPlexSetSupport(rdm, newp, supportRef);
2798: #if defined(PETSC_USE_DEBUG)
2799: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2800: for (p = 0; p < 2+size; ++p) {
2801: 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);
2802: }
2803: #endif
2804: }
2805: /* Cell vertices have 4 supports */
2806: for (c = cStart; c < cEnd; ++c) {
2807: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2808: PetscInt supportNew[4];
2810: for (r = 0; r < 4; ++r) {
2811: supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
2812: }
2813: DMPlexSetSupport(rdm, newp, supportNew);
2814: }
2815: PetscFree(supportRef);
2816: break;
2817: case REFINER_HYBRID_SIMPLEX_2D:
2818: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2819: cMax = PetscMin(cEnd, cMax);
2820: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
2821: fMax = PetscMin(fEnd, fMax);
2822: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);
2823: /* Interior cells have 3 faces */
2824: for (c = cStart; c < cMax; ++c) {
2825: const PetscInt newp = cStartNew + (c - cStart)*4;
2826: const PetscInt *cone, *ornt;
2827: PetscInt coneNew[3], orntNew[3];
2829: DMPlexGetCone(dm, c, &cone);
2830: DMPlexGetConeOrientation(dm, c, &ornt);
2831: /* A triangle */
2832: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2833: orntNew[0] = ornt[0];
2834: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2;
2835: orntNew[1] = -2;
2836: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2837: orntNew[2] = ornt[2];
2838: DMPlexSetCone(rdm, newp+0, coneNew);
2839: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2840: #if defined(PETSC_USE_DEBUG)
2841: 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);
2842: for (p = 0; p < 3; ++p) {
2843: 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);
2844: }
2845: #endif
2846: /* B triangle */
2847: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2848: orntNew[0] = ornt[0];
2849: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2850: orntNew[1] = ornt[1];
2851: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0;
2852: orntNew[2] = -2;
2853: DMPlexSetCone(rdm, newp+1, coneNew);
2854: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2855: #if defined(PETSC_USE_DEBUG)
2856: 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);
2857: for (p = 0; p < 3; ++p) {
2858: 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);
2859: }
2860: #endif
2861: /* C triangle */
2862: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1;
2863: orntNew[0] = -2;
2864: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2865: orntNew[1] = ornt[1];
2866: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2867: orntNew[2] = ornt[2];
2868: DMPlexSetCone(rdm, newp+2, coneNew);
2869: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2870: #if defined(PETSC_USE_DEBUG)
2871: 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);
2872: for (p = 0; p < 3; ++p) {
2873: 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);
2874: }
2875: #endif
2876: /* D triangle */
2877: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0;
2878: orntNew[0] = 0;
2879: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1;
2880: orntNew[1] = 0;
2881: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2;
2882: orntNew[2] = 0;
2883: DMPlexSetCone(rdm, newp+3, coneNew);
2884: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2885: #if defined(PETSC_USE_DEBUG)
2886: 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);
2887: for (p = 0; p < 3; ++p) {
2888: 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);
2889: }
2890: #endif
2891: }
2892: /*
2893: 2----3----3
2894: | |
2895: | B |
2896: | |
2897: 0----4--- 1
2898: | |
2899: | A |
2900: | |
2901: 0----2----1
2902: */
2903: /* Hybrid cells have 4 faces */
2904: for (c = cMax; c < cEnd; ++c) {
2905: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
2906: const PetscInt *cone, *ornt;
2907: PetscInt coneNew[4], orntNew[4], r;
2909: DMPlexGetCone(dm, c, &cone);
2910: DMPlexGetConeOrientation(dm, c, &ornt);
2911: r = (ornt[0] < 0 ? 1 : 0);
2912: /* A quad */
2913: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r;
2914: orntNew[0] = ornt[0];
2915: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r;
2916: orntNew[1] = ornt[1];
2917: coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
2918: orntNew[2+r] = 0;
2919: coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
2920: orntNew[3-r] = 0;
2921: DMPlexSetCone(rdm, newp+0, coneNew);
2922: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2923: #if defined(PETSC_USE_DEBUG)
2924: 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);
2925: for (p = 0; p < 4; ++p) {
2926: 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);
2927: }
2928: #endif
2929: /* B quad */
2930: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r;
2931: orntNew[0] = ornt[0];
2932: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r;
2933: orntNew[1] = ornt[1];
2934: coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
2935: orntNew[2+r] = 0;
2936: coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
2937: orntNew[3-r] = 0;
2938: DMPlexSetCone(rdm, newp+1, coneNew);
2939: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2940: #if defined(PETSC_USE_DEBUG)
2941: 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);
2942: for (p = 0; p < 4; ++p) {
2943: 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);
2944: }
2945: #endif
2946: }
2947: /* Interior split faces have 2 vertices and the same cells as the parent */
2948: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2949: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2950: for (f = fStart; f < fMax; ++f) {
2951: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2953: for (r = 0; r < 2; ++r) {
2954: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2955: const PetscInt *cone, *ornt, *support;
2956: PetscInt coneNew[2], coneSize, c, supportSize, s;
2958: DMPlexGetCone(dm, f, &cone);
2959: coneNew[0] = vStartNew + (cone[0] - vStart);
2960: coneNew[1] = vStartNew + (cone[1] - vStart);
2961: coneNew[(r+1)%2] = newv;
2962: DMPlexSetCone(rdm, newp, coneNew);
2963: #if defined(PETSC_USE_DEBUG)
2964: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2965: for (p = 0; p < 2; ++p) {
2966: 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);
2967: }
2968: #endif
2969: DMPlexGetSupportSize(dm, f, &supportSize);
2970: DMPlexGetSupport(dm, f, &support);
2971: for (s = 0; s < supportSize; ++s) {
2972: DMPlexGetConeSize(dm, support[s], &coneSize);
2973: DMPlexGetCone(dm, support[s], &cone);
2974: DMPlexGetConeOrientation(dm, support[s], &ornt);
2975: for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
2976: if (support[s] >= cMax) {
2977: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
2978: } else {
2979: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
2980: }
2981: }
2982: DMPlexSetSupport(rdm, newp, supportRef);
2983: #if defined(PETSC_USE_DEBUG)
2984: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2985: for (p = 0; p < supportSize; ++p) {
2986: 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);
2987: }
2988: #endif
2989: }
2990: }
2991: /* Interior cell faces have 2 vertices and 2 cells */
2992: for (c = cStart; c < cMax; ++c) {
2993: const PetscInt *cone;
2995: DMPlexGetCone(dm, c, &cone);
2996: for (r = 0; r < 3; ++r) {
2997: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
2998: PetscInt coneNew[2];
2999: PetscInt supportNew[2];
3001: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
3002: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
3003: DMPlexSetCone(rdm, newp, coneNew);
3004: #if defined(PETSC_USE_DEBUG)
3005: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3006: for (p = 0; p < 2; ++p) {
3007: 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);
3008: }
3009: #endif
3010: supportNew[0] = (c - cStart)*4 + (r+1)%3;
3011: supportNew[1] = (c - cStart)*4 + 3;
3012: DMPlexSetSupport(rdm, newp, supportNew);
3013: #if defined(PETSC_USE_DEBUG)
3014: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3015: for (p = 0; p < 2; ++p) {
3016: 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);
3017: }
3018: #endif
3019: }
3020: }
3021: /* Interior hybrid faces have 2 vertices and the same cells */
3022: for (f = fMax; f < fEnd; ++f) {
3023: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
3024: const PetscInt *cone, *ornt;
3025: const PetscInt *support;
3026: PetscInt coneNew[2];
3027: PetscInt supportNew[2];
3028: PetscInt size, s, r;
3030: DMPlexGetCone(dm, f, &cone);
3031: coneNew[0] = vStartNew + (cone[0] - vStart);
3032: coneNew[1] = vStartNew + (cone[1] - vStart);
3033: DMPlexSetCone(rdm, newp, coneNew);
3034: #if defined(PETSC_USE_DEBUG)
3035: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3036: for (p = 0; p < 2; ++p) {
3037: 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);
3038: }
3039: #endif
3040: DMPlexGetSupportSize(dm, f, &size);
3041: DMPlexGetSupport(dm, f, &support);
3042: for (s = 0; s < size; ++s) {
3043: DMPlexGetCone(dm, support[s], &cone);
3044: DMPlexGetConeOrientation(dm, support[s], &ornt);
3045: for (r = 0; r < 2; ++r) {
3046: if (cone[r+2] == f) break;
3047: }
3048: supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
3049: }
3050: DMPlexSetSupport(rdm, newp, supportNew);
3051: #if defined(PETSC_USE_DEBUG)
3052: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3053: for (p = 0; p < size; ++p) {
3054: 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);
3055: }
3056: #endif
3057: }
3058: /* Cell hybrid faces have 2 vertices and 2 cells */
3059: for (c = cMax; c < cEnd; ++c) {
3060: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
3061: const PetscInt *cone;
3062: PetscInt coneNew[2];
3063: PetscInt supportNew[2];
3065: DMPlexGetCone(dm, c, &cone);
3066: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
3067: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
3068: DMPlexSetCone(rdm, newp, coneNew);
3069: #if defined(PETSC_USE_DEBUG)
3070: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3071: for (p = 0; p < 2; ++p) {
3072: 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);
3073: }
3074: #endif
3075: supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
3076: supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
3077: DMPlexSetSupport(rdm, newp, supportNew);
3078: #if defined(PETSC_USE_DEBUG)
3079: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3080: for (p = 0; p < 2; ++p) {
3081: 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);
3082: }
3083: #endif
3084: }
3085: /* Old vertices have identical supports */
3086: for (v = vStart; v < vEnd; ++v) {
3087: const PetscInt newp = vStartNew + (v - vStart);
3088: const PetscInt *support, *cone;
3089: PetscInt size, s;
3091: DMPlexGetSupportSize(dm, v, &size);
3092: DMPlexGetSupport(dm, v, &support);
3093: for (s = 0; s < size; ++s) {
3094: if (support[s] >= fMax) {
3095: supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
3096: } else {
3097: PetscInt r = 0;
3099: DMPlexGetCone(dm, support[s], &cone);
3100: if (cone[1] == v) r = 1;
3101: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
3102: }
3103: }
3104: DMPlexSetSupport(rdm, newp, supportRef);
3105: #if defined(PETSC_USE_DEBUG)
3106: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3107: for (p = 0; p < size; ++p) {
3108: 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);
3109: }
3110: #endif
3111: }
3112: /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
3113: for (f = fStart; f < fMax; ++f) {
3114: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
3115: const PetscInt *cone, *support;
3116: PetscInt size, newSize = 2, s;
3118: DMPlexGetSupportSize(dm, f, &size);
3119: DMPlexGetSupport(dm, f, &support);
3120: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
3121: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
3122: for (s = 0; s < size; ++s) {
3123: PetscInt r = 0;
3125: DMPlexGetCone(dm, support[s], &cone);
3126: if (support[s] >= cMax) {
3127: supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
3129: newSize += 1;
3130: } else {
3131: if (cone[1] == f) r = 1;
3132: else if (cone[2] == f) r = 2;
3133: supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
3134: supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
3136: newSize += 2;
3137: }
3138: }
3139: DMPlexSetSupport(rdm, newp, supportRef);
3140: #if defined(PETSC_USE_DEBUG)
3141: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3142: for (p = 0; p < newSize; ++p) {
3143: 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);
3144: }
3145: #endif
3146: }
3147: PetscFree(supportRef);
3148: break;
3149: case REFINER_HYBRID_HEX_2D:
3150: /* Hybrid Hex 2D */
3151: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
3152: cMax = PetscMin(cEnd, cMax);
3153: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
3154: fMax = PetscMin(fEnd, fMax);
3155: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);
3156: /* Interior cells have 4 faces */
3157: for (c = cStart; c < cMax; ++c) {
3158: const PetscInt newp = cStartNew + (c - cStart)*4;
3159: const PetscInt *cone, *ornt;
3160: PetscInt coneNew[4], orntNew[4];
3162: DMPlexGetCone(dm, c, &cone);
3163: DMPlexGetConeOrientation(dm, c, &ornt);
3164: /* A quad */
3165: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
3166: orntNew[0] = ornt[0];
3167: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0;
3168: orntNew[1] = 0;
3169: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3;
3170: orntNew[2] = -2;
3171: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
3172: orntNew[3] = ornt[3];
3173: DMPlexSetCone(rdm, newp+0, coneNew);
3174: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3175: #if defined(PETSC_USE_DEBUG)
3176: 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);
3177: for (p = 0; p < 4; ++p) {
3178: 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);
3179: }
3180: #endif
3181: /* B quad */
3182: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
3183: orntNew[0] = ornt[0];
3184: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
3185: orntNew[1] = ornt[1];
3186: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1;
3187: orntNew[2] = 0;
3188: coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0;
3189: orntNew[3] = -2;
3190: DMPlexSetCone(rdm, newp+1, coneNew);
3191: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3192: #if defined(PETSC_USE_DEBUG)
3193: 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);
3194: for (p = 0; p < 4; ++p) {
3195: 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);
3196: }
3197: #endif
3198: /* C quad */
3199: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1;
3200: orntNew[0] = -2;
3201: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
3202: orntNew[1] = ornt[1];
3203: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
3204: orntNew[2] = ornt[2];
3205: coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2;
3206: orntNew[3] = 0;
3207: DMPlexSetCone(rdm, newp+2, coneNew);
3208: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3209: #if defined(PETSC_USE_DEBUG)
3210: 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);
3211: for (p = 0; p < 4; ++p) {
3212: 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);
3213: }
3214: #endif
3215: /* D quad */
3216: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3;
3217: orntNew[0] = 0;
3218: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2;
3219: orntNew[1] = -2;
3220: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
3221: orntNew[2] = ornt[2];
3222: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
3223: orntNew[3] = ornt[3];
3224: DMPlexSetCone(rdm, newp+3, coneNew);
3225: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3226: #if defined(PETSC_USE_DEBUG)
3227: 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);
3228: for (p = 0; p < 4; ++p) {
3229: 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);
3230: }
3231: #endif
3232: }
3233: /*
3234: 2----3----3
3235: | |
3236: | B |
3237: | |
3238: 0----4--- 1
3239: | |
3240: | A |
3241: | |
3242: 0----2----1
3243: */
3244: /* Hybrid cells have 4 faces */
3245: for (c = cMax; c < cEnd; ++c) {
3246: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
3247: const PetscInt *cone, *ornt;
3248: PetscInt coneNew[4], orntNew[4];
3250: DMPlexGetCone(dm, c, &cone);
3251: DMPlexGetConeOrientation(dm, c, &ornt);
3252: /* A quad */
3253: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
3254: orntNew[0] = ornt[0];
3255: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
3256: orntNew[1] = ornt[1];
3257: coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
3258: orntNew[2] = 0;
3259: coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
3260: orntNew[3] = 0;
3261: DMPlexSetCone(rdm, newp+0, coneNew);
3262: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3263: #if defined(PETSC_USE_DEBUG)
3264: 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);
3265: for (p = 0; p < 4; ++p) {
3266: 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);
3267: }
3268: #endif
3269: /* B quad */
3270: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
3271: orntNew[0] = ornt[0];
3272: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
3273: orntNew[1] = ornt[1];
3274: coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
3275: orntNew[2] = 0;
3276: coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
3277: orntNew[3] = 0;
3278: DMPlexSetCone(rdm, newp+1, coneNew);
3279: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3280: #if defined(PETSC_USE_DEBUG)
3281: 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);
3282: for (p = 0; p < 4; ++p) {
3283: 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);
3284: }
3285: #endif
3286: }
3287: /* Interior split faces have 2 vertices and the same cells as the parent */
3288: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
3289: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
3290: for (f = fStart; f < fMax; ++f) {
3291: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
3293: for (r = 0; r < 2; ++r) {
3294: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
3295: const PetscInt *cone, *ornt, *support;
3296: PetscInt coneNew[2], coneSize, c, supportSize, s;
3298: DMPlexGetCone(dm, f, &cone);
3299: coneNew[0] = vStartNew + (cone[0] - vStart);
3300: coneNew[1] = vStartNew + (cone[1] - vStart);
3301: coneNew[(r+1)%2] = newv;
3302: DMPlexSetCone(rdm, newp, coneNew);
3303: #if defined(PETSC_USE_DEBUG)
3304: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3305: for (p = 0; p < 2; ++p) {
3306: 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);
3307: }
3308: #endif
3309: DMPlexGetSupportSize(dm, f, &supportSize);
3310: DMPlexGetSupport(dm, f, &support);
3311: for (s = 0; s < supportSize; ++s) {
3312: if (support[s] >= cMax) {
3313: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
3314: } else {
3315: DMPlexGetConeSize(dm, support[s], &coneSize);
3316: DMPlexGetCone(dm, support[s], &cone);
3317: DMPlexGetConeOrientation(dm, support[s], &ornt);
3318: for (c = 0; c < coneSize; ++c) {
3319: if (cone[c] == f) break;
3320: }
3321: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
3322: }
3323: }
3324: DMPlexSetSupport(rdm, newp, supportRef);
3325: #if defined(PETSC_USE_DEBUG)
3326: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3327: for (p = 0; p < supportSize; ++p) {
3328: 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);
3329: }
3330: #endif
3331: }
3332: }
3333: /* Interior cell faces have 2 vertices and 2 cells */
3334: for (c = cStart; c < cMax; ++c) {
3335: const PetscInt *cone;
3337: DMPlexGetCone(dm, c, &cone);
3338: for (r = 0; r < 4; ++r) {
3339: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
3340: PetscInt coneNew[2], supportNew[2];
3342: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
3343: coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
3344: DMPlexSetCone(rdm, newp, coneNew);
3345: #if defined(PETSC_USE_DEBUG)
3346: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3347: for (p = 0; p < 2; ++p) {
3348: 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);
3349: }
3350: #endif
3351: supportNew[0] = (c - cStart)*4 + r;
3352: supportNew[1] = (c - cStart)*4 + (r+1)%4;
3353: DMPlexSetSupport(rdm, newp, supportNew);
3354: #if defined(PETSC_USE_DEBUG)
3355: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3356: for (p = 0; p < 2; ++p) {
3357: 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);
3358: }
3359: #endif
3360: }
3361: }
3362: /* Hybrid faces have 2 vertices and the same cells */
3363: for (f = fMax; f < fEnd; ++f) {
3364: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
3365: const PetscInt *cone, *support;
3366: PetscInt coneNew[2], supportNew[2];
3367: PetscInt size, s, r;
3369: DMPlexGetCone(dm, f, &cone);
3370: coneNew[0] = vStartNew + (cone[0] - vStart);
3371: coneNew[1] = vStartNew + (cone[1] - vStart);
3372: DMPlexSetCone(rdm, newp, coneNew);
3373: #if defined(PETSC_USE_DEBUG)
3374: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3375: for (p = 0; p < 2; ++p) {
3376: 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);
3377: }
3378: #endif
3379: DMPlexGetSupportSize(dm, f, &size);
3380: DMPlexGetSupport(dm, f, &support);
3381: for (s = 0; s < size; ++s) {
3382: DMPlexGetCone(dm, support[s], &cone);
3383: for (r = 0; r < 2; ++r) {
3384: if (cone[r+2] == f) break;
3385: }
3386: supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
3387: }
3388: DMPlexSetSupport(rdm, newp, supportNew);
3389: #if defined(PETSC_USE_DEBUG)
3390: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3391: for (p = 0; p < size; ++p) {
3392: 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);
3393: }
3394: #endif
3395: }
3396: /* Cell hybrid faces have 2 vertices and 2 cells */
3397: for (c = cMax; c < cEnd; ++c) {
3398: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
3399: const PetscInt *cone;
3400: PetscInt coneNew[2], supportNew[2];
3402: DMPlexGetCone(dm, c, &cone);
3403: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
3404: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
3405: DMPlexSetCone(rdm, newp, coneNew);
3406: #if defined(PETSC_USE_DEBUG)
3407: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3408: for (p = 0; p < 2; ++p) {
3409: 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);
3410: }
3411: #endif
3412: supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
3413: supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
3414: DMPlexSetSupport(rdm, newp, supportNew);
3415: #if defined(PETSC_USE_DEBUG)
3416: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3417: for (p = 0; p < 2; ++p) {
3418: 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);
3419: }
3420: #endif
3421: }
3422: /* Old vertices have identical supports */
3423: for (v = vStart; v < vEnd; ++v) {
3424: const PetscInt newp = vStartNew + (v - vStart);
3425: const PetscInt *support, *cone;
3426: PetscInt size, s;
3428: DMPlexGetSupportSize(dm, v, &size);
3429: DMPlexGetSupport(dm, v, &support);
3430: for (s = 0; s < size; ++s) {
3431: if (support[s] >= fMax) {
3432: supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
3433: } else {
3434: PetscInt r = 0;
3436: DMPlexGetCone(dm, support[s], &cone);
3437: if (cone[1] == v) r = 1;
3438: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
3439: }
3440: }
3441: DMPlexSetSupport(rdm, newp, supportRef);
3442: #if defined(PETSC_USE_DEBUG)
3443: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3444: for (p = 0; p < size; ++p) {
3445: 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);
3446: }
3447: #endif
3448: }
3449: /* Face vertices have 2 + cells supports */
3450: for (f = fStart; f < fMax; ++f) {
3451: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
3452: const PetscInt *cone, *support;
3453: PetscInt size, s;
3455: DMPlexGetSupportSize(dm, f, &size);
3456: DMPlexGetSupport(dm, f, &support);
3457: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
3458: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
3459: for (s = 0; s < size; ++s) {
3460: PetscInt r = 0;
3462: DMPlexGetCone(dm, support[s], &cone);
3463: if (support[s] >= cMax) {
3464: supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
3465: } else {
3466: if (cone[1] == f) r = 1;
3467: else if (cone[2] == f) r = 2;
3468: else if (cone[3] == f) r = 3;
3469: supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
3470: }
3471: }
3472: DMPlexSetSupport(rdm, newp, supportRef);
3473: #if defined(PETSC_USE_DEBUG)
3474: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3475: for (p = 0; p < 2+size; ++p) {
3476: 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);
3477: }
3478: #endif
3479: }
3480: /* Cell vertices have 4 supports */
3481: for (c = cStart; c < cMax; ++c) {
3482: const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
3483: PetscInt supportNew[4];
3485: for (r = 0; r < 4; ++r) {
3486: supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
3487: }
3488: DMPlexSetSupport(rdm, newp, supportNew);
3489: }
3490: PetscFree(supportRef);
3491: break;
3492: case REFINER_SIMPLEX_3D:
3493: /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
3494: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
3495: for (c = cStart; c < cEnd; ++c) {
3496: const PetscInt newp = cStartNew + (c - cStart)*8;
3497: const PetscInt *cone, *ornt;
3498: PetscInt coneNew[4], orntNew[4];
3500: DMPlexGetCone(dm, c, &cone);
3501: DMPlexGetConeOrientation(dm, c, &ornt);
3502: /* A tetrahedron: {0, a, c, d} */
3503: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
3504: orntNew[0] = ornt[0];
3505: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
3506: orntNew[1] = ornt[1];
3507: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
3508: orntNew[2] = ornt[2];
3509: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0;
3510: orntNew[3] = 0;
3511: DMPlexSetCone(rdm, newp+0, coneNew);
3512: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3513: #if defined(PETSC_USE_DEBUG)
3514: 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);
3515: for (p = 0; p < 4; ++p) {
3516: 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);
3517: }
3518: #endif
3519: /* B tetrahedron: {a, 1, b, e} */
3520: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
3521: orntNew[0] = ornt[0];
3522: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
3523: orntNew[1] = ornt[1];
3524: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1;
3525: orntNew[2] = 0;
3526: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
3527: orntNew[3] = ornt[3];
3528: DMPlexSetCone(rdm, newp+1, coneNew);
3529: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3530: #if defined(PETSC_USE_DEBUG)
3531: 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);
3532: for (p = 0; p < 4; ++p) {
3533: 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);
3534: }
3535: #endif
3536: /* C tetrahedron: {c, b, 2, f} */
3537: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
3538: orntNew[0] = ornt[0];
3539: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2;
3540: orntNew[1] = 0;
3541: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
3542: orntNew[2] = ornt[2];
3543: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
3544: orntNew[3] = ornt[3];
3545: DMPlexSetCone(rdm, newp+2, coneNew);
3546: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3547: #if defined(PETSC_USE_DEBUG)
3548: 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);
3549: for (p = 0; p < 4; ++p) {
3550: 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);
3551: }
3552: #endif
3553: /* D tetrahedron: {d, e, f, 3} */
3554: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3;
3555: orntNew[0] = 0;
3556: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
3557: orntNew[1] = ornt[1];
3558: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
3559: orntNew[2] = ornt[2];
3560: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
3561: orntNew[3] = ornt[3];
3562: DMPlexSetCone(rdm, newp+3, coneNew);
3563: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3564: #if defined(PETSC_USE_DEBUG)
3565: 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);
3566: for (p = 0; p < 4; ++p) {
3567: 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);
3568: }
3569: #endif
3570: /* A' tetrahedron: {c, d, a, f} */
3571: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0;
3572: orntNew[0] = -3;
3573: coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
3574: orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
3575: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3576: orntNew[2] = 0;
3577: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3578: orntNew[3] = 2;
3579: DMPlexSetCone(rdm, newp+4, coneNew);
3580: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
3581: #if defined(PETSC_USE_DEBUG)
3582: 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);
3583: for (p = 0; p < 4; ++p) {
3584: 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);
3585: }
3586: #endif
3587: /* B' tetrahedron: {e, b, a, f} */
3588: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1;
3589: orntNew[0] = -2;
3590: coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
3591: orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1);
3592: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3593: orntNew[2] = 0;
3594: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3595: orntNew[3] = 0;
3596: DMPlexSetCone(rdm, newp+5, coneNew);
3597: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
3598: #if defined(PETSC_USE_DEBUG)
3599: 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);
3600: for (p = 0; p < 4; ++p) {
3601: 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);
3602: }
3603: #endif
3604: /* C' tetrahedron: {f, a, c, b} */
3605: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3606: orntNew[0] = -2;
3607: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3608: orntNew[1] = -2;
3609: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2;
3610: orntNew[2] = -1;
3611: coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3;
3612: orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
3613: DMPlexSetCone(rdm, newp+6, coneNew);
3614: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
3615: #if defined(PETSC_USE_DEBUG)
3616: 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);
3617: for (p = 0; p < 4; ++p) {
3618: 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);
3619: }
3620: #endif
3621: /* D' tetrahedron: {f, a, e, d} */
3622: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3623: orntNew[0] = -2;
3624: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3625: orntNew[1] = -1;
3626: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3;
3627: orntNew[2] = -2;
3628: coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
3629: orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1);
3630: DMPlexSetCone(rdm, newp+7, coneNew);
3631: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
3632: #if defined(PETSC_USE_DEBUG)
3633: 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);
3634: for (p = 0; p < 4; ++p) {
3635: 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);
3636: }
3637: #endif
3638: }
3639: /* Split faces have 3 edges and the same cells as the parent */
3640: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
3641: PetscMalloc1(2 + maxSupportSize*3, &supportRef);
3642: for (f = fStart; f < fEnd; ++f) {
3643: const PetscInt newp = fStartNew + (f - fStart)*4;
3644: const PetscInt *cone, *ornt, *support;
3645: PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s;
3647: DMPlexGetCone(dm, f, &cone);
3648: DMPlexGetConeOrientation(dm, f, &ornt);
3649: /* A triangle */
3650: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
3651: orntNew[0] = ornt[0];
3652: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
3653: orntNew[1] = -2;
3654: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
3655: orntNew[2] = ornt[2];
3656: DMPlexSetCone(rdm, newp+0, coneNew);
3657: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3658: #if defined(PETSC_USE_DEBUG)
3659: 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);
3660: for (p = 0; p < 3; ++p) {
3661: 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);
3662: }
3663: #endif
3664: /* B triangle */
3665: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
3666: orntNew[0] = ornt[0];
3667: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
3668: orntNew[1] = ornt[1];
3669: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
3670: orntNew[2] = -2;
3671: DMPlexSetCone(rdm, newp+1, coneNew);
3672: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3673: #if defined(PETSC_USE_DEBUG)
3674: 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);
3675: for (p = 0; p < 3; ++p) {
3676: 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);
3677: }
3678: #endif
3679: /* C triangle */
3680: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
3681: orntNew[0] = -2;
3682: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
3683: orntNew[1] = ornt[1];
3684: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
3685: orntNew[2] = ornt[2];
3686: DMPlexSetCone(rdm, newp+2, coneNew);
3687: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3688: #if defined(PETSC_USE_DEBUG)
3689: 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);
3690: for (p = 0; p < 3; ++p) {
3691: 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);
3692: }
3693: #endif
3694: /* D triangle */
3695: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
3696: orntNew[0] = 0;
3697: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
3698: orntNew[1] = 0;
3699: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
3700: orntNew[2] = 0;
3701: DMPlexSetCone(rdm, newp+3, coneNew);
3702: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3703: #if defined(PETSC_USE_DEBUG)
3704: 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);
3705: for (p = 0; p < 3; ++p) {
3706: 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);
3707: }
3708: #endif
3709: DMPlexGetSupportSize(dm, f, &supportSize);
3710: DMPlexGetSupport(dm, f, &support);
3711: for (r = 0; r < 4; ++r) {
3712: for (s = 0; s < supportSize; ++s) {
3713: PetscInt subf;
3714: DMPlexGetConeSize(dm, support[s], &coneSize);
3715: DMPlexGetCone(dm, support[s], &cone);
3716: DMPlexGetConeOrientation(dm, support[s], &ornt);
3717: for (c = 0; c < coneSize; ++c) {
3718: if (cone[c] == f) break;
3719: }
3720: subf = GetTriSubfaceInverse_Static(ornt[c], r);
3721: supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
3722: }
3723: DMPlexSetSupport(rdm, newp+r, supportRef);
3724: #if defined(PETSC_USE_DEBUG)
3725: 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);
3726: for (p = 0; p < supportSize; ++p) {
3727: 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);
3728: }
3729: #endif
3730: }
3731: }
3732: /* Interior faces have 3 edges and 2 cells */
3733: for (c = cStart; c < cEnd; ++c) {
3734: PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
3735: const PetscInt *cone, *ornt;
3736: PetscInt coneNew[3], orntNew[3];
3737: PetscInt supportNew[2];
3739: DMPlexGetCone(dm, c, &cone);
3740: DMPlexGetConeOrientation(dm, c, &ornt);
3741: /* Face A: {c, a, d} */
3742: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3743: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3744: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3745: orntNew[1] = ornt[1] < 0 ? -2 : 0;
3746: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
3747: orntNew[2] = ornt[2] < 0 ? -2 : 0;
3748: DMPlexSetCone(rdm, newp, coneNew);
3749: DMPlexSetConeOrientation(rdm, newp, orntNew);
3750: #if defined(PETSC_USE_DEBUG)
3751: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3752: for (p = 0; p < 3; ++p) {
3753: 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);
3754: }
3755: #endif
3756: supportNew[0] = (c - cStart)*8 + 0;
3757: supportNew[1] = (c - cStart)*8 + 0+4;
3758: DMPlexSetSupport(rdm, newp, supportNew);
3759: #if defined(PETSC_USE_DEBUG)
3760: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3761: for (p = 0; p < 2; ++p) {
3762: 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);
3763: }
3764: #endif
3765: ++newp;
3766: /* Face B: {a, b, e} */
3767: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3768: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3769: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
3770: orntNew[1] = ornt[3] < 0 ? -2 : 0;
3771: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3772: orntNew[2] = ornt[1] < 0 ? -2 : 0;
3773: DMPlexSetCone(rdm, newp, coneNew);
3774: DMPlexSetConeOrientation(rdm, newp, orntNew);
3775: #if defined(PETSC_USE_DEBUG)
3776: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3777: for (p = 0; p < 3; ++p) {
3778: 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);
3779: }
3780: #endif
3781: supportNew[0] = (c - cStart)*8 + 1;
3782: supportNew[1] = (c - cStart)*8 + 1+4;
3783: DMPlexSetSupport(rdm, newp, supportNew);
3784: #if defined(PETSC_USE_DEBUG)
3785: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3786: for (p = 0; p < 2; ++p) {
3787: 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);
3788: }
3789: #endif
3790: ++newp;
3791: /* Face C: {c, f, b} */
3792: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
3793: orntNew[0] = ornt[2] < 0 ? -2 : 0;
3794: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3795: orntNew[1] = ornt[3] < 0 ? -2 : 0;
3796: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
3797: orntNew[2] = ornt[0] < 0 ? -2 : 0;
3798: DMPlexSetCone(rdm, newp, coneNew);
3799: DMPlexSetConeOrientation(rdm, newp, orntNew);
3800: #if defined(PETSC_USE_DEBUG)
3801: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3802: for (p = 0; p < 3; ++p) {
3803: 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);
3804: }
3805: #endif
3806: supportNew[0] = (c - cStart)*8 + 2;
3807: supportNew[1] = (c - cStart)*8 + 2+4;
3808: DMPlexSetSupport(rdm, newp, supportNew);
3809: #if defined(PETSC_USE_DEBUG)
3810: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3811: for (p = 0; p < 2; ++p) {
3812: 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);
3813: }
3814: #endif
3815: ++newp;
3816: /* Face D: {d, e, f} */
3817: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
3818: orntNew[0] = ornt[1] < 0 ? -2 : 0;
3819: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3820: orntNew[1] = ornt[3] < 0 ? -2 : 0;
3821: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3822: orntNew[2] = ornt[2] < 0 ? -2 : 0;
3823: DMPlexSetCone(rdm, newp, coneNew);
3824: DMPlexSetConeOrientation(rdm, newp, orntNew);
3825: #if defined(PETSC_USE_DEBUG)
3826: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3827: for (p = 0; p < 3; ++p) {
3828: 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);
3829: }
3830: #endif
3831: supportNew[0] = (c - cStart)*8 + 3;
3832: supportNew[1] = (c - cStart)*8 + 3+4;
3833: DMPlexSetSupport(rdm, newp, supportNew);
3834: #if defined(PETSC_USE_DEBUG)
3835: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3836: for (p = 0; p < 2; ++p) {
3837: 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);
3838: }
3839: #endif
3840: ++newp;
3841: /* Face E: {d, f, a} */
3842: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3843: orntNew[0] = ornt[2] < 0 ? 0 : -2;
3844: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3845: orntNew[1] = -2;
3846: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3847: orntNew[2] = ornt[1] < 0 ? -2 : 0;
3848: DMPlexSetCone(rdm, newp, coneNew);
3849: DMPlexSetConeOrientation(rdm, newp, orntNew);
3850: #if defined(PETSC_USE_DEBUG)
3851: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3852: for (p = 0; p < 3; ++p) {
3853: 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);
3854: }
3855: #endif
3856: supportNew[0] = (c - cStart)*8 + 0+4;
3857: supportNew[1] = (c - cStart)*8 + 3+4;
3858: DMPlexSetSupport(rdm, newp, supportNew);
3859: #if defined(PETSC_USE_DEBUG)
3860: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3861: for (p = 0; p < 2; ++p) {
3862: 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);
3863: }
3864: #endif
3865: ++newp;
3866: /* Face F: {c, a, f} */
3867: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3868: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3869: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3870: orntNew[1] = 0;
3871: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
3872: orntNew[2] = ornt[2] < 0 ? 0 : -2;
3873: DMPlexSetCone(rdm, newp, coneNew);
3874: DMPlexSetConeOrientation(rdm, newp, orntNew);
3875: #if defined(PETSC_USE_DEBUG)
3876: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3877: for (p = 0; p < 3; ++p) {
3878: 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);
3879: }
3880: #endif
3881: supportNew[0] = (c - cStart)*8 + 0+4;
3882: supportNew[1] = (c - cStart)*8 + 2+4;
3883: DMPlexSetSupport(rdm, newp, supportNew);
3884: #if defined(PETSC_USE_DEBUG)
3885: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3886: for (p = 0; p < 2; ++p) {
3887: 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);
3888: }
3889: #endif
3890: ++newp;
3891: /* Face G: {e, a, f} */
3892: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3893: orntNew[0] = ornt[1] < 0 ? -2 : 0;
3894: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3895: orntNew[1] = 0;
3896: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3897: orntNew[2] = ornt[3] < 0 ? 0 : -2;
3898: DMPlexSetCone(rdm, newp, coneNew);
3899: DMPlexSetConeOrientation(rdm, newp, orntNew);
3900: #if defined(PETSC_USE_DEBUG)
3901: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3902: for (p = 0; p < 3; ++p) {
3903: 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);
3904: }
3905: #endif
3906: supportNew[0] = (c - cStart)*8 + 1+4;
3907: supportNew[1] = (c - cStart)*8 + 3+4;
3908: DMPlexSetSupport(rdm, newp, supportNew);
3909: #if defined(PETSC_USE_DEBUG)
3910: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3911: for (p = 0; p < 2; ++p) {
3912: 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);
3913: }
3914: #endif
3915: ++newp;
3916: /* Face H: {a, b, f} */
3917: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3918: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3919: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3920: orntNew[1] = ornt[3] < 0 ? 0 : -2;
3921: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3922: orntNew[2] = -2;
3923: DMPlexSetCone(rdm, newp, coneNew);
3924: DMPlexSetConeOrientation(rdm, newp, orntNew);
3925: #if defined(PETSC_USE_DEBUG)
3926: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3927: for (p = 0; p < 3; ++p) {
3928: 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);
3929: }
3930: #endif
3931: supportNew[0] = (c - cStart)*8 + 1+4;
3932: supportNew[1] = (c - cStart)*8 + 2+4;
3933: DMPlexSetSupport(rdm, newp, supportNew);
3934: #if defined(PETSC_USE_DEBUG)
3935: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3936: for (p = 0; p < 2; ++p) {
3937: 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);
3938: }
3939: #endif
3940: ++newp;
3941: }
3942: /* Split Edges have 2 vertices and the same faces as the parent */
3943: for (e = eStart; e < eEnd; ++e) {
3944: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
3946: for (r = 0; r < 2; ++r) {
3947: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
3948: const PetscInt *cone, *ornt, *support;
3949: PetscInt coneNew[2], coneSize, c, supportSize, s;
3951: DMPlexGetCone(dm, e, &cone);
3952: coneNew[0] = vStartNew + (cone[0] - vStart);
3953: coneNew[1] = vStartNew + (cone[1] - vStart);
3954: coneNew[(r+1)%2] = newv;
3955: DMPlexSetCone(rdm, newp, coneNew);
3956: #if defined(PETSC_USE_DEBUG)
3957: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
3958: for (p = 0; p < 2; ++p) {
3959: 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);
3960: }
3961: #endif
3962: DMPlexGetSupportSize(dm, e, &supportSize);
3963: DMPlexGetSupport(dm, e, &support);
3964: for (s = 0; s < supportSize; ++s) {
3965: DMPlexGetConeSize(dm, support[s], &coneSize);
3966: DMPlexGetCone(dm, support[s], &cone);
3967: DMPlexGetConeOrientation(dm, support[s], &ornt);
3968: for (c = 0; c < coneSize; ++c) {
3969: if (cone[c] == e) break;
3970: }
3971: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
3972: }
3973: DMPlexSetSupport(rdm, newp, supportRef);
3974: #if defined(PETSC_USE_DEBUG)
3975: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
3976: for (p = 0; p < supportSize; ++p) {
3977: 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);
3978: }
3979: #endif
3980: }
3981: }
3982: /* Face edges have 2 vertices and 2+cells*(1/2) faces */
3983: for (f = fStart; f < fEnd; ++f) {
3984: const PetscInt *cone, *ornt, *support;
3985: PetscInt coneSize, supportSize, s;
3987: DMPlexGetSupportSize(dm, f, &supportSize);
3988: DMPlexGetSupport(dm, f, &support);
3989: for (r = 0; r < 3; ++r) {
3990: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
3991: PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
3992: PetscInt fint[24] = { 1, 7, -1, -1, 0, 5,
3993: -1, -1, 1, 6, 0, 4,
3994: 2, 5, 3, 4, -1, -1,
3995: -1, -1, 3, 6, 2, 7};
3997: DMPlexGetCone(dm, f, &cone);
3998: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
3999: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
4000: DMPlexSetCone(rdm, newp, coneNew);
4001: #if defined(PETSC_USE_DEBUG)
4002: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
4003: for (p = 0; p < 2; ++p) {
4004: 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);
4005: }
4006: #endif
4007: supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
4008: supportRef[1] = fStartNew + (f - fStart)*4 + 3;
4009: for (s = 0; s < supportSize; ++s) {
4010: DMPlexGetConeSize(dm, support[s], &coneSize);
4011: DMPlexGetCone(dm, support[s], &cone);
4012: DMPlexGetConeOrientation(dm, support[s], &ornt);
4013: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
4014: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4015: er = GetTriMidEdgeInverse_Static(ornt[c], r);
4016: if (er == eint[c]) {
4017: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
4018: } else {
4019: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
4020: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
4021: }
4022: }
4023: DMPlexSetSupport(rdm, newp, supportRef);
4024: #if defined(PETSC_USE_DEBUG)
4025: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
4026: for (p = 0; p < intFaces; ++p) {
4027: 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);
4028: }
4029: #endif
4030: }
4031: }
4032: /* Interior edges have 2 vertices and 4 faces */
4033: for (c = cStart; c < cEnd; ++c) {
4034: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
4035: const PetscInt *cone, *ornt, *fcone;
4036: PetscInt coneNew[2], supportNew[4], find;
4038: DMPlexGetCone(dm, c, &cone);
4039: DMPlexGetConeOrientation(dm, c, &ornt);
4040: DMPlexGetCone(dm, cone[0], &fcone);
4041: find = GetTriEdge_Static(ornt[0], 0);
4042: coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
4043: DMPlexGetCone(dm, cone[2], &fcone);
4044: find = GetTriEdge_Static(ornt[2], 1);
4045: coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
4046: DMPlexSetCone(rdm, newp, coneNew);
4047: #if defined(PETSC_USE_DEBUG)
4048: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
4049: for (p = 0; p < 2; ++p) {
4050: 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);
4051: }
4052: #endif
4053: supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
4054: supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
4055: supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
4056: supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
4057: DMPlexSetSupport(rdm, newp, supportNew);
4058: #if defined(PETSC_USE_DEBUG)
4059: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
4060: for (p = 0; p < 4; ++p) {
4061: 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);
4062: }
4063: #endif
4064: }
4065: /* Old vertices have identical supports */
4066: for (v = vStart; v < vEnd; ++v) {
4067: const PetscInt newp = vStartNew + (v - vStart);
4068: const PetscInt *support, *cone;
4069: PetscInt size, s;
4071: DMPlexGetSupportSize(dm, v, &size);
4072: DMPlexGetSupport(dm, v, &support);
4073: for (s = 0; s < size; ++s) {
4074: PetscInt r = 0;
4076: DMPlexGetCone(dm, support[s], &cone);
4077: if (cone[1] == v) r = 1;
4078: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4079: }
4080: DMPlexSetSupport(rdm, newp, supportRef);
4081: #if defined(PETSC_USE_DEBUG)
4082: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
4083: for (p = 0; p < size; ++p) {
4084: 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);
4085: }
4086: #endif
4087: }
4088: /* Edge vertices have 2 + face*2 + 0/1 supports */
4089: for (e = eStart; e < eEnd; ++e) {
4090: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
4091: const PetscInt *cone, *support;
4092: PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s;
4094: DMPlexGetSupportSize(dm, e, &size);
4095: DMPlexGetSupport(dm, e, &support);
4096: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4097: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4098: for (s = 0; s < size; ++s) {
4099: PetscInt r = 0;
4101: DMPlexGetConeSize(dm, support[s], &coneSize);
4102: DMPlexGetCone(dm, support[s], &cone);
4103: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
4104: supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
4105: supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
4106: }
4107: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
4108: for (s = 0; s < starSize*2; s += 2) {
4109: const PetscInt *cone, *ornt;
4110: PetscInt e01, e23;
4112: if ((star[s] >= cStart) && (star[s] < cEnd)) {
4113: /* Check edge 0-1 */
4114: DMPlexGetCone(dm, star[s], &cone);
4115: DMPlexGetConeOrientation(dm, star[s], &ornt);
4116: DMPlexGetCone(dm, cone[0], &cone);
4117: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
4118: /* Check edge 2-3 */
4119: DMPlexGetCone(dm, star[s], &cone);
4120: DMPlexGetConeOrientation(dm, star[s], &ornt);
4121: DMPlexGetCone(dm, cone[2], &cone);
4122: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
4123: if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
4124: }
4125: }
4126: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
4127: DMPlexSetSupport(rdm, newp, supportRef);
4128: #if defined(PETSC_USE_DEBUG)
4129: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
4130: for (p = 0; p < 2+size*2+cellSize; ++p) {
4131: 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);
4132: }
4133: #endif
4134: }
4135: PetscFree(supportRef);
4136: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
4137: break;
4138: case REFINER_HYBRID_SIMPLEX_3D:
4139: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);
4140: /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
4141: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
4142: for (c = cStart; c < cMax; ++c) {
4143: const PetscInt newp = cStartNew + (c - cStart)*8;
4144: const PetscInt *cone, *ornt;
4145: PetscInt coneNew[4], orntNew[4];
4147: DMPlexGetCone(dm, c, &cone);
4148: DMPlexGetConeOrientation(dm, c, &ornt);
4149: /* A tetrahedron: {0, a, c, d} */
4150: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
4151: orntNew[0] = ornt[0];
4152: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
4153: orntNew[1] = ornt[1];
4154: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
4155: orntNew[2] = ornt[2];
4156: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0;
4157: orntNew[3] = 0;
4158: DMPlexSetCone(rdm, newp+0, coneNew);
4159: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
4160: #if defined(PETSC_USE_DEBUG)
4161: 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);
4162: for (p = 0; p < 4; ++p) {
4163: 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);
4164: }
4165: #endif
4166: /* B tetrahedron: {a, 1, b, e} */
4167: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
4168: orntNew[0] = ornt[0];
4169: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
4170: orntNew[1] = ornt[1];
4171: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1;
4172: orntNew[2] = 0;
4173: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
4174: orntNew[3] = ornt[3];
4175: DMPlexSetCone(rdm, newp+1, coneNew);
4176: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
4177: #if defined(PETSC_USE_DEBUG)
4178: 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);
4179: for (p = 0; p < 4; ++p) {
4180: 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);
4181: }
4182: #endif
4183: /* C tetrahedron: {c, b, 2, f} */
4184: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
4185: orntNew[0] = ornt[0];
4186: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2;
4187: orntNew[1] = 0;
4188: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
4189: orntNew[2] = ornt[2];
4190: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
4191: orntNew[3] = ornt[3];
4192: DMPlexSetCone(rdm, newp+2, coneNew);
4193: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
4194: #if defined(PETSC_USE_DEBUG)
4195: 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);
4196: for (p = 0; p < 4; ++p) {
4197: 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);
4198: }
4199: #endif
4200: /* D tetrahedron: {d, e, f, 3} */
4201: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3;
4202: orntNew[0] = 0;
4203: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
4204: orntNew[1] = ornt[1];
4205: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
4206: orntNew[2] = ornt[2];
4207: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
4208: orntNew[3] = ornt[3];
4209: DMPlexSetCone(rdm, newp+3, coneNew);
4210: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
4211: #if defined(PETSC_USE_DEBUG)
4212: 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);
4213: for (p = 0; p < 4; ++p) {
4214: 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);
4215: }
4216: #endif
4217: /* A' tetrahedron: {d, a, c, f} */
4218: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0;
4219: orntNew[0] = -3;
4220: coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
4221: orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
4222: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
4223: orntNew[2] = 0;
4224: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
4225: orntNew[3] = 2;
4226: DMPlexSetCone(rdm, newp+4, coneNew);
4227: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
4228: #if defined(PETSC_USE_DEBUG)
4229: 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);
4230: for (p = 0; p < 4; ++p) {
4231: 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);
4232: }
4233: #endif
4234: /* B' tetrahedron: {e, b, a, f} */
4235: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1;
4236: orntNew[0] = -3;
4237: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
4238: orntNew[1] = 1;
4239: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
4240: orntNew[2] = 0;
4241: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
4242: orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0);
4243: DMPlexSetCone(rdm, newp+5, coneNew);
4244: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
4245: #if defined(PETSC_USE_DEBUG)
4246: 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);
4247: for (p = 0; p < 4; ++p) {
4248: 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);
4249: }
4250: #endif
4251: /* C' tetrahedron: {b, f, c, a} */
4252: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2;
4253: orntNew[0] = -3;
4254: coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
4255: orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
4256: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
4257: orntNew[2] = -3;
4258: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
4259: orntNew[3] = -2;
4260: DMPlexSetCone(rdm, newp+6, coneNew);
4261: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
4262: #if defined(PETSC_USE_DEBUG)
4263: 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);
4264: for (p = 0; p < 4; ++p) {
4265: 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);
4266: }
4267: #endif
4268: /* D' tetrahedron: {f, e, d, a} */
4269: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3;
4270: orntNew[0] = -3;
4271: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
4272: orntNew[1] = -3;
4273: coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
4274: orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0);
4275: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
4276: orntNew[3] = -3;
4277: DMPlexSetCone(rdm, newp+7, coneNew);
4278: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
4279: #if defined(PETSC_USE_DEBUG)
4280: 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);
4281: for (p = 0; p < 4; ++p) {
4282: 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);
4283: }
4284: #endif
4285: }
4286: /* Hybrid cells have 5 faces */
4287: for (c = cMax; c < cEnd; ++c) {
4288: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
4289: const PetscInt *cone, *ornt, *fornt;
4290: PetscInt coneNew[5], orntNew[5], o, of, i;
4292: DMPlexGetCone(dm, c, &cone);
4293: DMPlexGetConeOrientation(dm, c, &ornt);
4294: DMPlexGetConeOrientation(dm, cone[0], &fornt);
4295: o = ornt[0] < 0 ? -1 : 1;
4296: for (r = 0; r < 3; ++r) {
4297: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
4298: orntNew[0] = ornt[0];
4299: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
4300: orntNew[1] = ornt[1];
4301: of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1;
4302: i = GetTriEdgeInverse_Static(ornt[0], r) + 2;
4303: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0);
4304: orntNew[i] = 0;
4305: i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
4306: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
4307: orntNew[i] = 0;
4308: of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
4309: i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
4310: 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);
4311: orntNew[i] = 0;
4312: DMPlexSetCone(rdm, newp+r, coneNew);
4313: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
4314: #if defined(PETSC_USE_DEBUG)
4315: 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);
4316: for (p = 0; p < 2; ++p) {
4317: 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);
4318: }
4319: for (p = 2; p < 5; ++p) {
4320: 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);
4321: }
4322: #endif
4323: }
4324: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
4325: orntNew[0] = 0;
4326: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
4327: orntNew[1] = 0;
4328: coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
4329: orntNew[2] = 0;
4330: coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
4331: orntNew[3] = 0;
4332: coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
4333: orntNew[4] = 0;
4334: DMPlexSetCone(rdm, newp+3, coneNew);
4335: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
4336: #if defined(PETSC_USE_DEBUG)
4337: 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);
4338: for (p = 0; p < 2; ++p) {
4339: 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);
4340: }
4341: for (p = 2; p < 5; ++p) {
4342: 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);
4343: }
4344: #endif
4345: }
4346: /* Split faces have 3 edges and the same cells as the parent */
4347: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
4348: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
4349: for (f = fStart; f < fMax; ++f) {
4350: const PetscInt newp = fStartNew + (f - fStart)*4;
4351: const PetscInt *cone, *ornt, *support;
4352: PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s;
4354: DMPlexGetCone(dm, f, &cone);
4355: DMPlexGetConeOrientation(dm, f, &ornt);
4356: /* A triangle */
4357: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
4358: orntNew[0] = ornt[0];
4359: coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
4360: orntNew[1] = -2;
4361: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
4362: orntNew[2] = ornt[2];
4363: DMPlexSetCone(rdm, newp+0, coneNew);
4364: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
4365: #if defined(PETSC_USE_DEBUG)
4366: 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);
4367: for (p = 0; p < 3; ++p) {
4368: 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);
4369: }
4370: #endif
4371: /* B triangle */
4372: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
4373: orntNew[0] = ornt[0];
4374: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
4375: orntNew[1] = ornt[1];
4376: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
4377: orntNew[2] = -2;
4378: DMPlexSetCone(rdm, newp+1, coneNew);
4379: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
4380: #if defined(PETSC_USE_DEBUG)
4381: 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);
4382: for (p = 0; p < 3; ++p) {
4383: 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);
4384: }
4385: #endif
4386: /* C triangle */
4387: coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
4388: orntNew[0] = -2;
4389: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
4390: orntNew[1] = ornt[1];
4391: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
4392: orntNew[2] = ornt[2];
4393: DMPlexSetCone(rdm, newp+2, coneNew);
4394: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
4395: #if defined(PETSC_USE_DEBUG)
4396: 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);
4397: for (p = 0; p < 3; ++p) {
4398: 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);
4399: }
4400: #endif
4401: /* D triangle */
4402: coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
4403: orntNew[0] = 0;
4404: coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
4405: orntNew[1] = 0;
4406: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
4407: orntNew[2] = 0;
4408: DMPlexSetCone(rdm, newp+3, coneNew);
4409: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
4410: #if defined(PETSC_USE_DEBUG)
4411: 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);
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: DMPlexGetSupportSize(dm, f, &supportSize);
4417: DMPlexGetSupport(dm, f, &support);
4418: for (r = 0; r < 4; ++r) {
4419: for (s = 0; s < supportSize; ++s) {
4420: PetscInt subf;
4421: DMPlexGetConeSize(dm, support[s], &coneSize);
4422: DMPlexGetCone(dm, support[s], &cone);
4423: DMPlexGetConeOrientation(dm, support[s], &ornt);
4424: for (c = 0; c < coneSize; ++c) {
4425: if (cone[c] == f) break;
4426: }
4427: subf = GetTriSubfaceInverse_Static(ornt[c], r);
4428: if (support[s] < cMax) {
4429: supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
4430: } else {
4431: supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
4432: }
4433: }
4434: DMPlexSetSupport(rdm, newp+r, supportRef);
4435: #if defined(PETSC_USE_DEBUG)
4436: 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);
4437: for (p = 0; p < supportSize; ++p) {
4438: 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);
4439: }
4440: #endif
4441: }
4442: }
4443: /* Interior cell faces have 3 edges and 2 cells */
4444: for (c = cStart; c < cMax; ++c) {
4445: PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
4446: const PetscInt *cone, *ornt;
4447: PetscInt coneNew[3], orntNew[3];
4448: PetscInt supportNew[2];
4450: DMPlexGetCone(dm, c, &cone);
4451: DMPlexGetConeOrientation(dm, c, &ornt);
4452: /* Face A: {c, a, d} */
4453: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
4454: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4455: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
4456: orntNew[1] = ornt[1] < 0 ? -2 : 0;
4457: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
4458: orntNew[2] = ornt[2] < 0 ? -2 : 0;
4459: DMPlexSetCone(rdm, newp, coneNew);
4460: DMPlexSetConeOrientation(rdm, newp, orntNew);
4461: #if defined(PETSC_USE_DEBUG)
4462: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4463: for (p = 0; p < 3; ++p) {
4464: 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);
4465: }
4466: #endif
4467: supportNew[0] = (c - cStart)*8 + 0;
4468: supportNew[1] = (c - cStart)*8 + 0+4;
4469: DMPlexSetSupport(rdm, newp, supportNew);
4470: #if defined(PETSC_USE_DEBUG)
4471: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4472: for (p = 0; p < 2; ++p) {
4473: 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);
4474: }
4475: #endif
4476: ++newp;
4477: /* Face B: {a, b, e} */
4478: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
4479: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4480: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
4481: orntNew[1] = ornt[3] < 0 ? -2 : 0;
4482: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
4483: orntNew[2] = ornt[1] < 0 ? -2 : 0;
4484: DMPlexSetCone(rdm, newp, coneNew);
4485: DMPlexSetConeOrientation(rdm, newp, orntNew);
4486: #if defined(PETSC_USE_DEBUG)
4487: 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);
4488: for (p = 0; p < 3; ++p) {
4489: 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);
4490: }
4491: #endif
4492: supportNew[0] = (c - cStart)*8 + 1;
4493: supportNew[1] = (c - cStart)*8 + 1+4;
4494: DMPlexSetSupport(rdm, newp, supportNew);
4495: #if defined(PETSC_USE_DEBUG)
4496: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4497: for (p = 0; p < 2; ++p) {
4498: 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);
4499: }
4500: #endif
4501: ++newp;
4502: /* Face C: {c, f, b} */
4503: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
4504: orntNew[0] = ornt[2] < 0 ? -2 : 0;
4505: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
4506: orntNew[1] = ornt[3] < 0 ? -2 : 0;
4507: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
4508: orntNew[2] = ornt[0] < 0 ? -2 : 0;
4509: DMPlexSetCone(rdm, newp, coneNew);
4510: DMPlexSetConeOrientation(rdm, newp, orntNew);
4511: #if defined(PETSC_USE_DEBUG)
4512: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4513: for (p = 0; p < 3; ++p) {
4514: 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);
4515: }
4516: #endif
4517: supportNew[0] = (c - cStart)*8 + 2;
4518: supportNew[1] = (c - cStart)*8 + 2+4;
4519: DMPlexSetSupport(rdm, newp, supportNew);
4520: #if defined(PETSC_USE_DEBUG)
4521: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4522: for (p = 0; p < 2; ++p) {
4523: 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);
4524: }
4525: #endif
4526: ++newp;
4527: /* Face D: {d, e, f} */
4528: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
4529: orntNew[0] = ornt[1] < 0 ? -2 : 0;
4530: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
4531: orntNew[1] = ornt[3] < 0 ? -2 : 0;
4532: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
4533: orntNew[2] = ornt[2] < 0 ? -2 : 0;
4534: DMPlexSetCone(rdm, newp, coneNew);
4535: DMPlexSetConeOrientation(rdm, newp, orntNew);
4536: #if defined(PETSC_USE_DEBUG)
4537: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4538: for (p = 0; p < 3; ++p) {
4539: 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);
4540: }
4541: #endif
4542: supportNew[0] = (c - cStart)*8 + 3;
4543: supportNew[1] = (c - cStart)*8 + 3+4;
4544: DMPlexSetSupport(rdm, newp, supportNew);
4545: #if defined(PETSC_USE_DEBUG)
4546: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4547: for (p = 0; p < 2; ++p) {
4548: 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);
4549: }
4550: #endif
4551: ++newp;
4552: /* Face E: {d, f, a} */
4553: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
4554: orntNew[0] = ornt[2] < 0 ? 0 : -2;
4555: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4556: orntNew[1] = -2;
4557: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
4558: orntNew[2] = ornt[1] < 0 ? -2 : 0;
4559: DMPlexSetCone(rdm, newp, coneNew);
4560: DMPlexSetConeOrientation(rdm, newp, orntNew);
4561: #if defined(PETSC_USE_DEBUG)
4562: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4563: for (p = 0; p < 3; ++p) {
4564: 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);
4565: }
4566: #endif
4567: supportNew[0] = (c - cStart)*8 + 0+4;
4568: supportNew[1] = (c - cStart)*8 + 3+4;
4569: DMPlexSetSupport(rdm, newp, supportNew);
4570: #if defined(PETSC_USE_DEBUG)
4571: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4572: for (p = 0; p < 2; ++p) {
4573: 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);
4574: }
4575: #endif
4576: ++newp;
4577: /* Face F: {c, a, f} */
4578: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
4579: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4580: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4581: orntNew[1] = 0;
4582: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
4583: orntNew[2] = ornt[2] < 0 ? 0 : -2;
4584: DMPlexSetCone(rdm, newp, coneNew);
4585: DMPlexSetConeOrientation(rdm, newp, orntNew);
4586: #if defined(PETSC_USE_DEBUG)
4587: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4588: for (p = 0; p < 3; ++p) {
4589: 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);
4590: }
4591: #endif
4592: supportNew[0] = (c - cStart)*8 + 0+4;
4593: supportNew[1] = (c - cStart)*8 + 2+4;
4594: DMPlexSetSupport(rdm, newp, supportNew);
4595: #if defined(PETSC_USE_DEBUG)
4596: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4597: for (p = 0; p < 2; ++p) {
4598: 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);
4599: }
4600: #endif
4601: ++newp;
4602: /* Face G: {e, a, f} */
4603: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
4604: orntNew[0] = ornt[1] < 0 ? -2 : 0;
4605: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4606: orntNew[1] = 0;
4607: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
4608: orntNew[2] = ornt[3] < 0 ? 0 : -2;
4609: DMPlexSetCone(rdm, newp, coneNew);
4610: DMPlexSetConeOrientation(rdm, newp, orntNew);
4611: #if defined(PETSC_USE_DEBUG)
4612: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4613: for (p = 0; p < 3; ++p) {
4614: 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);
4615: }
4616: #endif
4617: supportNew[0] = (c - cStart)*8 + 1+4;
4618: supportNew[1] = (c - cStart)*8 + 3+4;
4619: DMPlexSetSupport(rdm, newp, supportNew);
4620: #if defined(PETSC_USE_DEBUG)
4621: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4622: for (p = 0; p < 2; ++p) {
4623: 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);
4624: }
4625: #endif
4626: ++newp;
4627: /* Face H: {a, b, f} */
4628: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
4629: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4630: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
4631: orntNew[1] = ornt[3] < 0 ? 0 : -2;
4632: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4633: orntNew[2] = -2;
4634: DMPlexSetCone(rdm, newp, coneNew);
4635: DMPlexSetConeOrientation(rdm, newp, orntNew);
4636: #if defined(PETSC_USE_DEBUG)
4637: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4638: for (p = 0; p < 3; ++p) {
4639: 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);
4640: }
4641: #endif
4642: supportNew[0] = (c - cStart)*8 + 1+4;
4643: supportNew[1] = (c - cStart)*8 + 2+4;
4644: DMPlexSetSupport(rdm, newp, supportNew);
4645: #if defined(PETSC_USE_DEBUG)
4646: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4647: for (p = 0; p < 2; ++p) {
4648: 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);
4649: }
4650: #endif
4651: ++newp;
4652: }
4653: /* Hybrid split faces have 4 edges and same cells */
4654: for (f = fMax; f < fEnd; ++f) {
4655: const PetscInt *cone, *ornt, *support;
4656: PetscInt coneNew[4], orntNew[4];
4657: PetscInt supportNew[2], size, s, c;
4659: DMPlexGetCone(dm, f, &cone);
4660: DMPlexGetConeOrientation(dm, f, &ornt);
4661: DMPlexGetSupportSize(dm, f, &size);
4662: DMPlexGetSupport(dm, f, &support);
4663: for (r = 0; r < 2; ++r) {
4664: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
4666: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
4667: orntNew[0] = ornt[0];
4668: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
4669: orntNew[1] = ornt[1];
4670: coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
4671: orntNew[2+r] = 0;
4672: coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
4673: orntNew[3-r] = 0;
4674: DMPlexSetCone(rdm, newp, coneNew);
4675: DMPlexSetConeOrientation(rdm, newp, orntNew);
4676: #if defined(PETSC_USE_DEBUG)
4677: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
4678: for (p = 0; p < 2; ++p) {
4679: 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);
4680: }
4681: for (p = 2; p < 4; ++p) {
4682: 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);
4683: }
4684: #endif
4685: for (s = 0; s < size; ++s) {
4686: const PetscInt *coneCell, *orntCell, *fornt;
4687: PetscInt o, of;
4689: DMPlexGetCone(dm, support[s], &coneCell);
4690: DMPlexGetConeOrientation(dm, support[s], &orntCell);
4691: o = orntCell[0] < 0 ? -1 : 1;
4692: for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
4693: if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]);
4694: DMPlexGetConeOrientation(dm, coneCell[0], &fornt);
4695: of = fornt[c-2] < 0 ? -1 : 1;
4696: supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3;
4697: }
4698: DMPlexSetSupport(rdm, newp, supportNew);
4699: #if defined(PETSC_USE_DEBUG)
4700: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
4701: for (p = 0; p < size; ++p) {
4702: 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);
4703: }
4704: #endif
4705: }
4706: }
4707: /* Hybrid cell faces have 4 edges and 2 cells */
4708: for (c = cMax; c < cEnd; ++c) {
4709: PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
4710: const PetscInt *cone, *ornt;
4711: PetscInt coneNew[4], orntNew[4];
4712: PetscInt supportNew[2];
4714: DMPlexGetCone(dm, c, &cone);
4715: DMPlexGetConeOrientation(dm, c, &ornt);
4716: for (r = 0; r < 3; ++r) {
4717: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
4718: orntNew[0] = 0;
4719: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
4720: orntNew[1] = 0;
4721: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
4722: orntNew[2] = 0;
4723: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax);
4724: orntNew[3] = 0;
4725: DMPlexSetCone(rdm, newp+r, coneNew);
4726: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
4727: #if defined(PETSC_USE_DEBUG)
4728: 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);
4729: for (p = 0; p < 2; ++p) {
4730: 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);
4731: }
4732: for (p = 2; p < 4; ++p) {
4733: 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);
4734: }
4735: #endif
4736: supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
4737: supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
4738: DMPlexSetSupport(rdm, newp+r, supportNew);
4739: #if defined(PETSC_USE_DEBUG)
4740: 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);
4741: for (p = 0; p < 2; ++p) {
4742: 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);
4743: }
4744: #endif
4745: }
4746: }
4747: /* Interior split edges have 2 vertices and the same faces as the parent */
4748: for (e = eStart; e < eMax; ++e) {
4749: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
4751: for (r = 0; r < 2; ++r) {
4752: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
4753: const PetscInt *cone, *ornt, *support;
4754: PetscInt coneNew[2], coneSize, c, supportSize, s;
4756: DMPlexGetCone(dm, e, &cone);
4757: coneNew[0] = vStartNew + (cone[0] - vStart);
4758: coneNew[1] = vStartNew + (cone[1] - vStart);
4759: coneNew[(r+1)%2] = newv;
4760: DMPlexSetCone(rdm, newp, coneNew);
4761: #if defined(PETSC_USE_DEBUG)
4762: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4763: for (p = 0; p < 2; ++p) {
4764: 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);
4765: }
4766: #endif
4767: DMPlexGetSupportSize(dm, e, &supportSize);
4768: DMPlexGetSupport(dm, e, &support);
4769: for (s = 0; s < supportSize; ++s) {
4770: DMPlexGetConeSize(dm, support[s], &coneSize);
4771: DMPlexGetCone(dm, support[s], &cone);
4772: DMPlexGetConeOrientation(dm, support[s], &ornt);
4773: for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
4774: if (support[s] < fMax) {
4775: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
4776: } else {
4777: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
4778: }
4779: }
4780: DMPlexSetSupport(rdm, newp, supportRef);
4781: #if defined(PETSC_USE_DEBUG)
4782: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4783: for (p = 0; p < supportSize; ++p) {
4784: 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);
4785: }
4786: #endif
4787: }
4788: }
4789: /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
4790: for (f = fStart; f < fMax; ++f) {
4791: const PetscInt *cone, *ornt, *support;
4792: PetscInt coneSize, supportSize, s;
4794: DMPlexGetSupportSize(dm, f, &supportSize);
4795: DMPlexGetSupport(dm, f, &support);
4796: for (r = 0; r < 3; ++r) {
4797: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
4798: PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
4799: PetscInt fint[24] = { 1, 7, -1, -1, 0, 5,
4800: -1, -1, 1, 6, 0, 4,
4801: 2, 5, 3, 4, -1, -1,
4802: -1, -1, 3, 6, 2, 7};
4804: DMPlexGetCone(dm, f, &cone);
4805: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
4806: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
4807: DMPlexSetCone(rdm, newp, coneNew);
4808: #if defined(PETSC_USE_DEBUG)
4809: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4810: for (p = 0; p < 2; ++p) {
4811: 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);
4812: }
4813: #endif
4814: supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
4815: supportRef[1] = fStartNew + (f - fStart)*4 + 3;
4816: for (s = 0; s < supportSize; ++s) {
4817: DMPlexGetConeSize(dm, support[s], &coneSize);
4818: DMPlexGetCone(dm, support[s], &cone);
4819: DMPlexGetConeOrientation(dm, support[s], &ornt);
4820: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
4821: if (support[s] < cMax) {
4822: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4823: er = GetTriMidEdgeInverse_Static(ornt[c], r);
4824: if (er == eint[c]) {
4825: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
4826: } else {
4827: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
4828: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
4829: }
4830: } else {
4831: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
4832: }
4833: }
4834: DMPlexSetSupport(rdm, newp, supportRef);
4835: #if defined(PETSC_USE_DEBUG)
4836: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4837: for (p = 0; p < intFaces; ++p) {
4838: 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);
4839: }
4840: #endif
4841: }
4842: }
4843: /* Interior cell edges have 2 vertices and 4 faces */
4844: for (c = cStart; c < cMax; ++c) {
4845: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4846: const PetscInt *cone, *ornt, *fcone;
4847: PetscInt coneNew[2], supportNew[4], find;
4849: DMPlexGetCone(dm, c, &cone);
4850: DMPlexGetConeOrientation(dm, c, &ornt);
4851: DMPlexGetCone(dm, cone[0], &fcone);
4852: find = GetTriEdge_Static(ornt[0], 0);
4853: coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
4854: DMPlexGetCone(dm, cone[2], &fcone);
4855: find = GetTriEdge_Static(ornt[2], 1);
4856: coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
4857: DMPlexSetCone(rdm, newp, coneNew);
4858: #if defined(PETSC_USE_DEBUG)
4859: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4860: for (p = 0; p < 2; ++p) {
4861: 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);
4862: }
4863: #endif
4864: supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
4865: supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
4866: supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
4867: supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
4868: DMPlexSetSupport(rdm, newp, supportNew);
4869: #if defined(PETSC_USE_DEBUG)
4870: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4871: for (p = 0; p < 4; ++p) {
4872: 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);
4873: }
4874: #endif
4875: }
4876: /* Hybrid edges have two vertices and the same faces */
4877: for (e = eMax; e < eEnd; ++e) {
4878: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
4879: const PetscInt *cone, *support, *fcone;
4880: PetscInt coneNew[2], size, fsize, s;
4882: DMPlexGetCone(dm, e, &cone);
4883: DMPlexGetSupportSize(dm, e, &size);
4884: DMPlexGetSupport(dm, e, &support);
4885: coneNew[0] = vStartNew + (cone[0] - vStart);
4886: coneNew[1] = vStartNew + (cone[1] - vStart);
4887: DMPlexSetCone(rdm, newp, coneNew);
4888: #if defined(PETSC_USE_DEBUG)
4889: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4890: for (p = 0; p < 2; ++p) {
4891: 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);
4892: }
4893: #endif
4894: for (s = 0; s < size; ++s) {
4895: DMPlexGetConeSize(dm, support[s], &fsize);
4896: DMPlexGetCone(dm, support[s], &fcone);
4897: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
4898: if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]);
4899: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
4900: }
4901: DMPlexSetSupport(rdm, newp, supportRef);
4902: #if defined(PETSC_USE_DEBUG)
4903: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4904: for (p = 0; p < size; ++p) {
4905: 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);
4906: }
4907: #endif
4908: }
4909: /* Hybrid face edges have 2 vertices and 2+2*cells faces */
4910: for (f = fMax; f < fEnd; ++f) {
4911: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
4912: const PetscInt *cone, *support, *ccone, *cornt;
4913: PetscInt coneNew[2], size, csize, s;
4915: DMPlexGetCone(dm, f, &cone);
4916: DMPlexGetSupportSize(dm, f, &size);
4917: DMPlexGetSupport(dm, f, &support);
4918: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
4919: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
4920: DMPlexSetCone(rdm, newp, coneNew);
4921: #if defined(PETSC_USE_DEBUG)
4922: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4923: for (p = 0; p < 2; ++p) {
4924: 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);
4925: }
4926: #endif
4927: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
4928: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
4929: for (s = 0; s < size; ++s) {
4930: DMPlexGetConeSize(dm, support[s], &csize);
4931: DMPlexGetCone(dm, support[s], &ccone);
4932: DMPlexGetConeOrientation(dm, support[s], &cornt);
4933: for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
4934: 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]);
4935: supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
4936: supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
4937: }
4938: DMPlexSetSupport(rdm, newp, supportRef);
4939: #if defined(PETSC_USE_DEBUG)
4940: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4941: for (p = 0; p < 2+size*2; ++p) {
4942: 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);
4943: }
4944: #endif
4945: }
4946: /* Interior vertices have identical supports */
4947: for (v = vStart; v < vEnd; ++v) {
4948: const PetscInt newp = vStartNew + (v - vStart);
4949: const PetscInt *support, *cone;
4950: PetscInt size, s;
4952: DMPlexGetSupportSize(dm, v, &size);
4953: DMPlexGetSupport(dm, v, &support);
4954: for (s = 0; s < size; ++s) {
4955: PetscInt r = 0;
4957: DMPlexGetCone(dm, support[s], &cone);
4958: if (cone[1] == v) r = 1;
4959: if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4960: else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
4961: }
4962: DMPlexSetSupport(rdm, newp, supportRef);
4963: #if defined(PETSC_USE_DEBUG)
4964: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
4965: for (p = 0; p < size; ++p) {
4966: 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);
4967: }
4968: #endif
4969: }
4970: /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
4971: for (e = eStart; e < eMax; ++e) {
4972: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
4973: const PetscInt *cone, *support;
4974: PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
4976: DMPlexGetSupportSize(dm, e, &size);
4977: DMPlexGetSupport(dm, e, &support);
4978: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4979: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4980: for (s = 0; s < size; ++s) {
4981: PetscInt r = 0;
4983: if (support[s] < fMax) {
4984: DMPlexGetConeSize(dm, support[s], &coneSize);
4985: DMPlexGetCone(dm, support[s], &cone);
4986: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
4987: supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
4988: supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
4989: faceSize += 2;
4990: } else {
4991: supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
4992: ++faceSize;
4993: }
4994: }
4995: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
4996: for (s = 0; s < starSize*2; s += 2) {
4997: const PetscInt *cone, *ornt;
4998: PetscInt e01, e23;
5000: if ((star[s] >= cStart) && (star[s] < cMax)) {
5001: /* Check edge 0-1 */
5002: DMPlexGetCone(dm, star[s], &cone);
5003: DMPlexGetConeOrientation(dm, star[s], &ornt);
5004: DMPlexGetCone(dm, cone[0], &cone);
5005: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
5006: /* Check edge 2-3 */
5007: DMPlexGetCone(dm, star[s], &cone);
5008: DMPlexGetConeOrientation(dm, star[s], &ornt);
5009: DMPlexGetCone(dm, cone[2], &cone);
5010: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
5011: if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
5012: }
5013: }
5014: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
5015: DMPlexSetSupport(rdm, newp, supportRef);
5016: #if defined(PETSC_USE_DEBUG)
5017: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5018: for (p = 0; p < 2+faceSize+cellSize; ++p) {
5019: 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);
5020: }
5021: #endif
5022: }
5023: PetscFree(supportRef);
5024: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
5025: break;
5026: case REFINER_SIMPLEX_TO_HEX_3D:
5027: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
5028: /* All cells have 6 faces */
5029: for (c = cStart; c < cEnd; ++c) {
5030: const PetscInt newp = cStartNew + (c - cStart)*4;
5031: const PetscInt *cone, *ornt;
5032: PetscInt coneNew[6];
5033: PetscInt orntNew[6];
5035: DMPlexGetCone(dm, c, &cone);
5036: DMPlexGetConeOrientation(dm, c, &ornt);
5037: /* A hex */
5038: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
5039: orntNew[0] = ornt[0] < 0 ? -1 : 1;
5040: coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */
5041: orntNew[1] = -4;
5042: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */
5043: orntNew[2] = ornt[2] < 0 ? -1 : 1;
5044: coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */
5045: orntNew[3] = -1;
5046: coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */
5047: orntNew[4] = 0;
5048: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */
5049: orntNew[5] = ornt[1] < 0 ? -1 : 1;
5050: DMPlexSetCone(rdm, newp+0, coneNew);
5051: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5052: #if defined(PETSC_USE_DEBUG)
5053: 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);
5054: for (p = 0; p < 6; ++p) {
5055: 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);
5056: }
5057: #endif
5058: /* B hex */
5059: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
5060: orntNew[0] = ornt[0] < 0 ? -2 : 0;
5061: coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */
5062: orntNew[1] = 0;
5063: coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */
5064: orntNew[2] = 0;
5065: coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */
5066: orntNew[3] = ornt[3] < 0 ? -2 : 0;
5067: coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */
5068: orntNew[4] = 0;
5069: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */
5070: orntNew[5] = ornt[1] < 0 ? -4 : 2;
5071: DMPlexSetCone(rdm, newp+1, coneNew);
5072: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5073: #if defined(PETSC_USE_DEBUG)
5074: 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);
5075: for (p = 0; p < 6; ++p) {
5076: 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);
5077: }
5078: #endif
5079: /* C hex */
5080: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
5081: orntNew[0] = ornt[0] < 0 ? -4 : 2;
5082: coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */
5083: orntNew[1] = -4;
5084: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */
5085: orntNew[2] = ornt[2] < 0 ? -2 : 0;
5086: coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */
5087: orntNew[3] = -1;
5088: coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */
5089: orntNew[4] = ornt[3] < 0 ? -1 : 1;
5090: coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */
5091: orntNew[5] = -4;
5092: DMPlexSetCone(rdm, newp+2, coneNew);
5093: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5094: #if defined(PETSC_USE_DEBUG)
5095: 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);
5096: for (p = 0; p < 6; ++p) {
5097: 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);
5098: }
5099: #endif
5100: /* D hex */
5101: coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */
5102: orntNew[0] = 0;
5103: coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */
5104: orntNew[1] = ornt[3] < 0 ? -1 : 1;
5105: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */
5106: orntNew[2] = ornt[2] < 0 ? -4 : 2;
5107: coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */
5108: orntNew[3] = -1;
5109: coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */
5110: orntNew[4] = 0;
5111: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */
5112: orntNew[5] = ornt[1] < 0 ? -2 : 0;
5113: DMPlexSetCone(rdm, newp+3, coneNew);
5114: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
5115: #if defined(PETSC_USE_DEBUG)
5116: 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);
5117: for (p = 0; p < 6; ++p) {
5118: 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);
5119: }
5120: #endif
5121: }
5122: /* Split faces have 4 edges and the same cells as the parent */
5123: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
5124: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
5125: for (f = fStart; f < fEnd; ++f) {
5126: const PetscInt newp = fStartNew + (f - fStart)*3;
5127: const PetscInt *cone, *ornt, *support;
5128: PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s;
5130: DMPlexGetCone(dm, f, &cone);
5131: DMPlexGetConeOrientation(dm, f, &ornt);
5132: /* A quad */
5133: coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
5134: orntNew[0] = ornt[2];
5135: coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
5136: orntNew[1] = ornt[0];
5137: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
5138: orntNew[2] = 0;
5139: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
5140: orntNew[3] = -2;
5141: DMPlexSetCone(rdm, newp+0, coneNew);
5142: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5143: #if defined(PETSC_USE_DEBUG)
5144: 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);
5145: for (p = 0; p < 4; ++p) {
5146: 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);
5147: }
5148: #endif
5149: /* B quad */
5150: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
5151: orntNew[0] = ornt[0];
5152: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
5153: orntNew[1] = ornt[1];
5154: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
5155: orntNew[2] = 0;
5156: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
5157: orntNew[3] = -2;
5158: DMPlexSetCone(rdm, newp+1, coneNew);
5159: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5160: #if defined(PETSC_USE_DEBUG)
5161: 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);
5162: for (p = 0; p < 4; ++p) {
5163: 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);
5164: }
5165: #endif
5166: /* C quad */
5167: coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
5168: orntNew[0] = ornt[1];
5169: coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
5170: orntNew[1] = ornt[2];
5171: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
5172: orntNew[2] = 0;
5173: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
5174: orntNew[3] = -2;
5175: DMPlexSetCone(rdm, newp+2, coneNew);
5176: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5177: #if defined(PETSC_USE_DEBUG)
5178: 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);
5179: for (p = 0; p < 4; ++p) {
5180: 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);
5181: }
5182: #endif
5183: DMPlexGetSupportSize(dm, f, &supportSize);
5184: DMPlexGetSupport(dm, f, &support);
5185: for (r = 0; r < 3; ++r) {
5186: for (s = 0; s < supportSize; ++s) {
5187: PetscInt subf;
5188: DMPlexGetConeSize(dm, support[s], &coneSize);
5189: DMPlexGetCone(dm, support[s], &cone);
5190: DMPlexGetConeOrientation(dm, support[s], &ornt);
5191: for (c = 0; c < coneSize; ++c) {
5192: if (cone[c] == f) break;
5193: }
5194: subf = GetTriSubfaceInverse_Static(ornt[c], r);
5195: supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf];
5196: }
5197: DMPlexSetSupport(rdm, newp+r, supportRef);
5198: #if defined(PETSC_USE_DEBUG)
5199: 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);
5200: for (p = 0; p < supportSize; ++p) {
5201: 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);
5202: }
5203: #endif
5204: }
5205: }
5206: /* Interior faces have 4 edges and 2 cells */
5207: for (c = cStart; c < cEnd; ++c) {
5208: PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6;
5209: const PetscInt *cone, *ornt;
5210: PetscInt coneNew[4], orntNew[4];
5211: PetscInt supportNew[2];
5213: DMPlexGetCone(dm, c, &cone);
5214: DMPlexGetConeOrientation(dm, c, &ornt);
5215: /* Face {a, g, m, h} */
5216: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
5217: orntNew[0] = 0;
5218: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5219: orntNew[1] = 0;
5220: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5221: orntNew[2] = -2;
5222: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
5223: orntNew[3] = -2;
5224: DMPlexSetCone(rdm, newp, coneNew);
5225: DMPlexSetConeOrientation(rdm, newp, orntNew);
5226: #if defined(PETSC_USE_DEBUG)
5227: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5228: for (p = 0; p < 4; ++p) {
5229: 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);
5230: }
5231: #endif
5232: supportNew[0] = (c - cStart)*4 + 0;
5233: supportNew[1] = (c - cStart)*4 + 1;
5234: DMPlexSetSupport(rdm, newp, supportNew);
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 < 2; ++p) {
5238: 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);
5239: }
5240: #endif
5241: ++newp;
5242: /* Face {g, b, l , m} */
5243: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
5244: orntNew[0] = -2;
5245: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0);
5246: orntNew[1] = 0;
5247: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5248: orntNew[2] = 0;
5249: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5250: orntNew[3] = -2;
5251: DMPlexSetCone(rdm, newp, coneNew);
5252: DMPlexSetConeOrientation(rdm, newp, orntNew);
5253: #if defined(PETSC_USE_DEBUG)
5254: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5255: for (p = 0; p < 4; ++p) {
5256: 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);
5257: }
5258: #endif
5259: supportNew[0] = (c - cStart)*4 + 1;
5260: supportNew[1] = (c - cStart)*4 + 2;
5261: DMPlexSetSupport(rdm, newp, supportNew);
5262: #if defined(PETSC_USE_DEBUG)
5263: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5264: for (p = 0; p < 2; ++p) {
5265: 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);
5266: }
5267: #endif
5268: ++newp;
5269: /* Face {c, g, m, i} */
5270: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
5271: orntNew[0] = 0;
5272: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5273: orntNew[1] = 0;
5274: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5275: orntNew[2] = -2;
5276: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0);
5277: orntNew[3] = -2;
5278: DMPlexSetCone(rdm, newp, coneNew);
5279: DMPlexSetConeOrientation(rdm, newp, orntNew);
5280: #if defined(PETSC_USE_DEBUG)
5281: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5282: for (p = 0; p < 4; ++p) {
5283: 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);
5284: }
5285: #endif
5286: supportNew[0] = (c - cStart)*4 + 0;
5287: supportNew[1] = (c - cStart)*4 + 2;
5288: DMPlexSetSupport(rdm, newp, supportNew);
5289: #if defined(PETSC_USE_DEBUG)
5290: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5291: for (p = 0; p < 2; ++p) {
5292: 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);
5293: }
5294: #endif
5295: ++newp;
5296: /* Face {d, h, m, i} */
5297: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
5298: orntNew[0] = 0;
5299: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5300: orntNew[1] = 0;
5301: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5302: orntNew[2] = -2;
5303: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2);
5304: orntNew[3] = -2;
5305: DMPlexSetCone(rdm, newp, coneNew);
5306: DMPlexSetConeOrientation(rdm, newp, orntNew);
5307: #if defined(PETSC_USE_DEBUG)
5308: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5309: for (p = 0; p < 4; ++p) {
5310: 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);
5311: }
5312: #endif
5313: supportNew[0] = (c - cStart)*4 + 0;
5314: supportNew[1] = (c - cStart)*4 + 3;
5315: DMPlexSetSupport(rdm, newp, supportNew);
5316: #if defined(PETSC_USE_DEBUG)
5317: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5318: for (p = 0; p < 2; ++p) {
5319: 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);
5320: }
5321: #endif
5322: ++newp;
5323: /* Face {h, m, l, e} */
5324: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5325: orntNew[0] = 0;
5326: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5327: orntNew[1] = -2;
5328: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1);
5329: orntNew[2] = -2;
5330: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
5331: orntNew[3] = 0;
5332: DMPlexSetCone(rdm, newp, coneNew);
5333: DMPlexSetConeOrientation(rdm, newp, orntNew);
5334: #if defined(PETSC_USE_DEBUG)
5335: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5336: for (p = 0; p < 4; ++p) {
5337: 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);
5338: }
5339: #endif
5340: supportNew[0] = (c - cStart)*4 + 1;
5341: supportNew[1] = (c - cStart)*4 + 3;
5342: DMPlexSetSupport(rdm, newp, supportNew);
5343: #if defined(PETSC_USE_DEBUG)
5344: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5345: for (p = 0; p < 2; ++p) {
5346: 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);
5347: }
5348: #endif
5349: ++newp;
5350: /* Face {i, m, l, f} */
5351: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5352: orntNew[0] = 0;
5353: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5354: orntNew[1] = -2;
5355: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2);
5356: orntNew[2] = -2;
5357: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1);
5358: orntNew[3] = 0;
5359: DMPlexSetCone(rdm, newp, coneNew);
5360: DMPlexSetConeOrientation(rdm, newp, orntNew);
5361: #if defined(PETSC_USE_DEBUG)
5362: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5363: for (p = 0; p < 4; ++p) {
5364: 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);
5365: }
5366: #endif
5367: supportNew[0] = (c - cStart)*4 + 2;
5368: supportNew[1] = (c - cStart)*4 + 3;
5369: DMPlexSetSupport(rdm, newp, supportNew);
5370: #if defined(PETSC_USE_DEBUG)
5371: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5372: for (p = 0; p < 2; ++p) {
5373: 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);
5374: }
5375: #endif
5376: ++newp;
5377: }
5378: /* Split Edges have 2 vertices and the same faces as the parent */
5379: for (e = eStart; e < eEnd; ++e) {
5380: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
5382: for (r = 0; r < 2; ++r) {
5383: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
5384: const PetscInt *cone, *ornt, *support;
5385: PetscInt coneNew[2], coneSize, c, supportSize, s;
5387: DMPlexGetCone(dm, e, &cone);
5388: coneNew[0] = vStartNew + (cone[0] - vStart);
5389: coneNew[1] = vStartNew + (cone[1] - vStart);
5390: coneNew[(r+1)%2] = newv;
5391: DMPlexSetCone(rdm, newp, coneNew);
5392: #if defined(PETSC_USE_DEBUG)
5393: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5394: for (p = 0; p < 2; ++p) {
5395: 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);
5396: }
5397: #endif
5398: DMPlexGetSupportSize(dm, e, &supportSize);
5399: DMPlexGetSupport(dm, e, &support);
5400: for (s = 0; s < supportSize; ++s) {
5401: DMPlexGetConeSize(dm, support[s], &coneSize);
5402: DMPlexGetCone(dm, support[s], &cone);
5403: DMPlexGetConeOrientation(dm, support[s], &ornt);
5404: for (c = 0; c < coneSize; ++c) {
5405: if (cone[c] == e) break;
5406: }
5407: supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3;
5408: }
5409: DMPlexSetSupport(rdm, newp, supportRef);
5410: #if defined(PETSC_USE_DEBUG)
5411: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5412: for (p = 0; p < supportSize; ++p) {
5413: 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);
5414: }
5415: #endif
5416: }
5417: }
5418: /* Face edges have 2 vertices and 2 + cell faces supports */
5419: for (f = fStart; f < fEnd; ++f) {
5420: const PetscInt *cone, *ornt, *support;
5421: PetscInt coneSize, supportSize, s;
5423: DMPlexGetSupportSize(dm, f, &supportSize);
5424: DMPlexGetSupport(dm, f, &support);
5425: for (r = 0; r < 3; ++r) {
5426: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
5427: PetscInt coneNew[2];
5428: PetscInt fint[4][3] = { {0, 1, 2},
5429: {3, 4, 0},
5430: {2, 5, 3},
5431: {1, 4, 5} };
5433: DMPlexGetCone(dm, f, &cone);
5434: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
5435: coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
5436: DMPlexSetCone(rdm, newp, coneNew);
5437: #if defined(PETSC_USE_DEBUG)
5438: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5439: for (p = 0; p < 2; ++p) {
5440: 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);
5441: }
5442: #endif
5443: supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3;
5444: supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3;
5445: for (s = 0; s < supportSize; ++s) {
5446: PetscInt er;
5447: DMPlexGetConeSize(dm, support[s], &coneSize);
5448: DMPlexGetCone(dm, support[s], &cone);
5449: DMPlexGetConeOrientation(dm, support[s], &ornt);
5450: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
5451: er = GetTriInteriorEdgeInverse_Static(ornt[c], r);
5452: supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er];
5453: }
5454: DMPlexSetSupport(rdm, newp, supportRef);
5455: #if defined(PETSC_USE_DEBUG)
5456: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5457: for (p = 0; p < supportSize + 2; ++p) {
5458: 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);
5459: }
5460: #endif
5461: }
5462: }
5463: /* Interior cell edges have 2 vertices and 3 faces */
5464: for (c = cStart; c < cEnd; ++c) {
5465: const PetscInt *cone;
5466: PetscInt fint[4][3] = { {0,1,2},
5467: {0,3,4},
5468: {2,3,5},
5469: {1,4,5} } ;
5471: DMPlexGetCone(dm, c, &cone);
5472: for (r = 0; r < 4; r++) {
5473: PetscInt coneNew[2], supportNew[3];
5474: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
5476: coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
5477: coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart;
5478: DMPlexSetCone(rdm, newp, coneNew);
5479: #if defined(PETSC_USE_DEBUG)
5480: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5481: for (p = 0; p < 2; ++p) {
5482: 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);
5483: }
5484: #endif
5485: supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0];
5486: supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1];
5487: supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2];
5488: DMPlexSetSupport(rdm, newp, supportNew);
5489: #if defined(PETSC_USE_DEBUG)
5490: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5491: for (p = 0; p < 3; ++p) {
5492: 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);
5493: }
5494: #endif
5495: }
5496: }
5497: /* Old vertices have identical supports */
5498: for (v = vStart; v < vEnd; ++v) {
5499: const PetscInt newp = vStartNew + (v - vStart);
5500: const PetscInt *support, *cone;
5501: PetscInt size, s;
5503: DMPlexGetSupportSize(dm, v, &size);
5504: DMPlexGetSupport(dm, v, &support);
5505: for (s = 0; s < size; ++s) {
5506: PetscInt r = 0;
5508: DMPlexGetCone(dm, support[s], &cone);
5509: if (cone[1] == v) r = 1;
5510: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
5511: }
5512: DMPlexSetSupport(rdm, newp, supportRef);
5513: #if defined(PETSC_USE_DEBUG)
5514: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5515: for (p = 0; p < size; ++p) {
5516: 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);
5517: }
5518: #endif
5519: }
5520: /* Edge vertices have 2 + faces supports */
5521: for (e = eStart; e < eEnd; ++e) {
5522: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
5523: const PetscInt *cone, *support;
5524: PetscInt size, s;
5526: DMPlexGetSupportSize(dm, e, &size);
5527: DMPlexGetSupport(dm, e, &support);
5528: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
5529: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
5530: for (s = 0; s < size; ++s) {
5531: PetscInt r = 0, coneSize;
5533: DMPlexGetConeSize(dm, support[s], &coneSize);
5534: DMPlexGetCone(dm, support[s], &cone);
5535: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
5536: supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r;
5537: }
5538: DMPlexSetSupport(rdm, newp, supportRef);
5539: #if defined(PETSC_USE_DEBUG)
5540: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5541: for (p = 0; p < 2+size; ++p) {
5542: 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);
5543: }
5544: #endif
5545: }
5546: /* Face vertices have 3 + cells supports */
5547: for (f = fStart; f < fEnd; ++f) {
5548: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
5549: const PetscInt *cone, *support;
5550: PetscInt size, s;
5552: DMPlexGetSupportSize(dm, f, &size);
5553: DMPlexGetSupport(dm, f, &support);
5554: supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
5555: supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
5556: supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
5557: for (s = 0; s < size; ++s) {
5558: PetscInt r = 0, coneSize;
5560: DMPlexGetConeSize(dm, support[s], &coneSize);
5561: DMPlexGetCone(dm, support[s], &cone);
5562: for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;}
5563: supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r;
5564: }
5565: DMPlexSetSupport(rdm, newp, supportRef);
5566: #if defined(PETSC_USE_DEBUG)
5567: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5568: for (p = 0; p < 3+size; ++p) {
5569: 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);
5570: }
5571: #endif
5572: }
5573: /* Interior cell vertices have 4 supports */
5574: for (c = cStart; c < cEnd; ++c) {
5575: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart;
5576: supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5577: supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5578: supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5579: supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5580: DMPlexSetSupport(rdm, newp, supportRef);
5581: #if defined(PETSC_USE_DEBUG)
5582: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5583: for (p = 0; p < 4; ++p) {
5584: 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);
5585: }
5586: #endif
5587: }
5588: PetscFree(supportRef);
5589: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
5590: break;
5591: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
5592: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
5593: cMax = PetscMin(cEnd, cMax);
5594: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
5595: fMax = PetscMin(fEnd, fMax);
5596: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
5597: eMax = PetscMin(eEnd, eMax);
5598: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
5599: /* All cells have 6 faces */
5600: for (c = cStart; c < cMax; ++c) {
5601: const PetscInt newp = cStartNew + (c - cStart)*4;
5602: const PetscInt *cone, *ornt;
5603: PetscInt coneNew[6];
5604: PetscInt orntNew[6];
5606: DMPlexGetCone(dm, c, &cone);
5607: #if defined(PETSC_USE_DEBUG)
5608: for (p = 0; p < 4; ++p) {
5609: 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);
5610: }
5611: #endif
5612: DMPlexGetConeOrientation(dm, c, &ornt);
5613: /* A hex */
5614: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
5615: orntNew[0] = ornt[0] < 0 ? -1 : 1;
5616: coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* T */
5617: orntNew[1] = -4;
5618: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */
5619: orntNew[2] = ornt[2] < 0 ? -1 : 1;
5620: coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* K */
5621: orntNew[3] = -1;
5622: coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* R */
5623: orntNew[4] = 0;
5624: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */
5625: orntNew[5] = ornt[1] < 0 ? -1 : 1;
5626: DMPlexSetCone(rdm, newp+0, coneNew);
5627: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5628: #if defined(PETSC_USE_DEBUG)
5629: 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);
5630: for (p = 0; p < 6; ++p) {
5631: 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);
5632: }
5633: #endif
5634: /* B hex */
5635: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
5636: orntNew[0] = ornt[0] < 0 ? -2 : 0;
5637: coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* T */
5638: orntNew[1] = 0;
5639: coneNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* F */
5640: orntNew[2] = 0;
5641: coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */
5642: orntNew[3] = ornt[3] < 0 ? -2 : 0;
5643: coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* R */
5644: orntNew[4] = 0;
5645: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */
5646: orntNew[5] = ornt[1] < 0 ? -4 : 2;
5647: DMPlexSetCone(rdm, newp+1, coneNew);
5648: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5649: #if defined(PETSC_USE_DEBUG)
5650: 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);
5651: for (p = 0; p < 6; ++p) {
5652: 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);
5653: }
5654: #endif
5655: /* C hex */
5656: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
5657: orntNew[0] = ornt[0] < 0 ? -4 : 2;
5658: coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* T */
5659: orntNew[1] = -4;
5660: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */
5661: orntNew[2] = ornt[2] < 0 ? -2 : 0;
5662: coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* K */
5663: orntNew[3] = -1;
5664: coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */
5665: orntNew[4] = ornt[3] < 0 ? -1 : 1;
5666: coneNew[5] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* L */
5667: orntNew[5] = -4;
5668: DMPlexSetCone(rdm, newp+2, coneNew);
5669: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5670: #if defined(PETSC_USE_DEBUG)
5671: 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);
5672: for (p = 0; p < 6; ++p) {
5673: 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);
5674: }
5675: #endif
5676: /* D hex */
5677: coneNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* B */
5678: orntNew[0] = 0;
5679: coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */
5680: orntNew[1] = ornt[3] < 0 ? -1 : 1;
5681: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */
5682: orntNew[2] = ornt[2] < 0 ? -4 : 2;
5683: coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* K */
5684: orntNew[3] = -1;
5685: coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* R */
5686: orntNew[4] = 0;
5687: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */
5688: orntNew[5] = ornt[1] < 0 ? -2 : 0;
5689: DMPlexSetCone(rdm, newp+3, coneNew);
5690: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
5691: #if defined(PETSC_USE_DEBUG)
5692: 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);
5693: for (p = 0; p < 6; ++p) {
5694: 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);
5695: }
5696: #endif
5697: }
5698: for (c = cMax; c < cEnd; ++c) {
5699: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3;
5700: const PetscInt *cone, *ornt;
5701: PetscInt coneNew[6], orntNew[6];
5702: PetscInt o, of, cf;
5704: DMPlexGetCone(dm, c, &cone);
5705: #if defined(PETSC_USE_DEBUG)
5706: 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);
5707: 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);
5708: 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);
5709: 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);
5710: 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);
5711: #endif
5712: DMPlexGetConeOrientation(dm, c, &ornt);
5713: o = ornt[0] < 0 ? -1 : 1;
5714: o = 1;
5715: /* A hex */
5716: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
5717: orntNew[0] = ornt[0] < 0 ? -1 : 1;
5718: coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* T */
5719: orntNew[1] = ornt[1] < 0 ? 1 : -1;
5720: cf = 2;
5721: of = ornt[2+cf] < 0 ? -1 : 1;
5722: coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* F */
5723: orntNew[2] = o*of < 0 ? 0 : -1;
5724: coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* K */
5725: orntNew[3] = -1;
5726: coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* R */
5727: orntNew[4] = 0;
5728: cf = 0;
5729: of = ornt[2+cf] < 0 ? -1 : 1;
5730: coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* L */
5731: orntNew[5] = o*of < 0 ? 1 : -4;
5732: DMPlexSetCone(rdm, newp+0, coneNew);
5733: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5734: #if defined(PETSC_USE_DEBUG)
5735: 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);
5736: for (p = 0; p < 6; ++p) {
5737: 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);
5738: }
5739: #endif
5740: /* B hex */
5741: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
5742: orntNew[0] = ornt[0] < 0 ? -2 : 0;
5743: coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* T */
5744: orntNew[1] = ornt[1] < 0 ? 2 : -4;
5745: coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* F */
5746: orntNew[2] = 0;
5747: cf = 1;
5748: of = ornt[2+cf] < 0 ? -1 : 1;
5749: coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* K */
5750: orntNew[3] = o*of < 0 ? 0 : -1;
5751: coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* R */
5752: orntNew[4] = -1;
5753: cf = 0;
5754: of = ornt[2+cf] < 0 ? -1 : 1;
5755: coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* L */
5756: orntNew[5] = o*of < 0 ? 1 : -4;
5757: DMPlexSetCone(rdm, newp+1, coneNew);
5758: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5759: #if defined(PETSC_USE_DEBUG)
5760: 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);
5761: for (p = 0; p < 6; ++p) {
5762: 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);
5763: }
5764: #endif
5765: /* C hex */
5766: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
5767: orntNew[0] = ornt[0] < 0 ? -4 : 2;
5768: coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* T */
5769: orntNew[1] = ornt[1] < 0 ? 0 : -2;
5770: cf = 2;
5771: of = ornt[2+cf] < 0 ? -1 : 1;
5772: coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* F */
5773: orntNew[2] = o*of < 0 ? 0 : -1;
5774: coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* K */
5775: orntNew[3] = 0;
5776: cf = 1;
5777: of = ornt[2+cf] < 0 ? -1 : 1;
5778: coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* R */
5779: orntNew[4] = o*of < 0 ? 0 : -1;
5780: coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* L */
5781: orntNew[5] = -4;
5782: DMPlexSetCone(rdm, newp+2, coneNew);
5783: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5784: #if defined(PETSC_USE_DEBUG)
5785: 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);
5786: for (p = 0; p < 6; ++p) {
5787: 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);
5788: }
5789: #endif
5790: }
5792: /* Split faces have 4 edges and the same cells as the parent */
5793: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
5794: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
5795: for (f = fStart; f < fMax; ++f) {
5796: const PetscInt newp = fStartNew + (f - fStart)*3;
5797: const PetscInt *cone, *ornt, *support;
5798: PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s;
5800: DMPlexGetCone(dm, f, &cone);
5801: #if defined(PETSC_USE_DEBUG)
5802: for (p = 0; p < 3; ++p) {
5803: 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);
5804: }
5805: #endif
5806: DMPlexGetConeOrientation(dm, f, &ornt);
5807: /* A quad */
5808: coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
5809: orntNew[0] = ornt[2];
5810: coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
5811: orntNew[1] = ornt[0];
5812: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
5813: orntNew[2] = 0;
5814: coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
5815: orntNew[3] = -2;
5816: DMPlexSetCone(rdm, newp+0, coneNew);
5817: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5818: #if defined(PETSC_USE_DEBUG)
5819: 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);
5820: for (p = 0; p < 4; ++p) {
5821: 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);
5822: }
5823: #endif
5824: /* B quad */
5825: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
5826: orntNew[0] = ornt[0];
5827: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
5828: orntNew[1] = ornt[1];
5829: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
5830: orntNew[2] = 0;
5831: coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
5832: orntNew[3] = -2;
5833: DMPlexSetCone(rdm, newp+1, coneNew);
5834: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5835: #if defined(PETSC_USE_DEBUG)
5836: 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);
5837: for (p = 0; p < 4; ++p) {
5838: 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);
5839: }
5840: #endif
5841: /* C quad */
5842: coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
5843: orntNew[0] = ornt[1];
5844: coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
5845: orntNew[1] = ornt[2];
5846: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
5847: orntNew[2] = 0;
5848: coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
5849: orntNew[3] = -2;
5850: DMPlexSetCone(rdm, newp+2, coneNew);
5851: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5852: #if defined(PETSC_USE_DEBUG)
5853: 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);
5854: for (p = 0; p < 4; ++p) {
5855: 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);
5856: }
5857: #endif
5858: DMPlexGetSupportSize(dm, f, &supportSize);
5859: DMPlexGetSupport(dm, f, &support);
5860: for (r = 0; r < 3; ++r) {
5861: for (s = 0; s < supportSize; ++s) {
5862: PetscInt subf;
5864: DMPlexGetConeSize(dm, support[s], &coneSize);
5865: 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);
5866: 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);
5867: DMPlexGetCone(dm, support[s], &cone);
5868: DMPlexGetConeOrientation(dm, support[s], &ornt);
5869: for (c = 0; c < coneSize; ++c) {
5870: if (cone[c] == f) break;
5871: }
5872: subf = GetTriSubfaceInverse_Static(ornt[c], r);
5873: if (coneSize == 4) {
5874: supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf];
5875: } else if (coneSize == 5) {
5876: 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);
5877: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + subf;
5878: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax);
5879: }
5880: DMPlexSetSupport(rdm, newp+r, supportRef);
5881: #if defined(PETSC_USE_DEBUG)
5882: 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);
5883: for (p = 0; p < supportSize; ++p) {
5884: 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);
5885: }
5886: #endif
5887: }
5888: }
5889: /* Interior faces have 4 edges and 2 cells */
5890: for (c = cStart; c < cMax; ++c) {
5891: PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6;
5892: const PetscInt *cone, *ornt;
5893: PetscInt coneNew[4], orntNew[4];
5894: PetscInt supportNew[2];
5896: DMPlexGetCone(dm, c, &cone);
5897: #if defined(PETSC_USE_DEBUG)
5898: for (p = 0; p < 4; ++p) {
5899: 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);
5900: }
5901: #endif
5902: DMPlexGetConeOrientation(dm, c, &ornt);
5903: /* Face {a, g, m, h} */
5904: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
5905: orntNew[0] = 0;
5906: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
5907: orntNew[1] = 0;
5908: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
5909: orntNew[2] = -2;
5910: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
5911: orntNew[3] = -2;
5912: DMPlexSetCone(rdm, newp, coneNew);
5913: DMPlexSetConeOrientation(rdm, newp, orntNew);
5914: #if defined(PETSC_USE_DEBUG)
5915: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5916: for (p = 0; p < 4; ++p) {
5917: 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);
5918: }
5919: #endif
5920: supportNew[0] = cStartNew + (c - cStart)*4 + 0;
5921: supportNew[1] = cStartNew + (c - cStart)*4 + 1;
5922: DMPlexSetSupport(rdm, newp, supportNew);
5923: #if defined(PETSC_USE_DEBUG)
5924: for (p = 0; p < 2; ++p) {
5925: 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);
5926: }
5927: #endif
5928: ++newp;
5929: /* Face {g, b, l , m} */
5930: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
5931: orntNew[0] = -2;
5932: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0);
5933: orntNew[1] = 0;
5934: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
5935: orntNew[2] = 0;
5936: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
5937: orntNew[3] = -2;
5938: DMPlexSetCone(rdm, newp, coneNew);
5939: DMPlexSetConeOrientation(rdm, newp, orntNew);
5940: #if defined(PETSC_USE_DEBUG)
5941: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5942: for (p = 0; p < 4; ++p) {
5943: 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);
5944: }
5945: #endif
5946: supportNew[0] = cStartNew + (c - cStart)*4 + 1;
5947: supportNew[1] = cStartNew + (c - cStart)*4 + 2;
5948: DMPlexSetSupport(rdm, newp, supportNew);
5949: #if defined(PETSC_USE_DEBUG)
5950: for (p = 0; p < 2; ++p) {
5951: 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);
5952: }
5953: #endif
5954: ++newp;
5955: /* Face {c, g, m, i} */
5956: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
5957: orntNew[0] = 0;
5958: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
5959: orntNew[1] = 0;
5960: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
5961: orntNew[2] = -2;
5962: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0);
5963: orntNew[3] = -2;
5964: DMPlexSetCone(rdm, newp, coneNew);
5965: DMPlexSetConeOrientation(rdm, newp, orntNew);
5966: #if defined(PETSC_USE_DEBUG)
5967: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5968: for (p = 0; p < 4; ++p) {
5969: 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);
5970: }
5971: #endif
5972: supportNew[0] = cStartNew + (c - cStart)*4 + 0;
5973: supportNew[1] = cStartNew + (c - cStart)*4 + 2;
5974: DMPlexSetSupport(rdm, newp, supportNew);
5975: #if defined(PETSC_USE_DEBUG)
5976: for (p = 0; p < 2; ++p) {
5977: 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);
5978: }
5979: #endif
5980: ++newp;
5981: /* Face {d, h, m, i} */
5982: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
5983: orntNew[0] = 0;
5984: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
5985: orntNew[1] = 0;
5986: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
5987: orntNew[2] = -2;
5988: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2);
5989: orntNew[3] = -2;
5990: DMPlexSetCone(rdm, newp, coneNew);
5991: DMPlexSetConeOrientation(rdm, newp, orntNew);
5992: #if defined(PETSC_USE_DEBUG)
5993: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5994: for (p = 0; p < 4; ++p) {
5995: 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);
5996: }
5997: #endif
5998: supportNew[0] = cStartNew + (c - cStart)*4 + 0;
5999: supportNew[1] = cStartNew + (c - cStart)*4 + 3;
6000: DMPlexSetSupport(rdm, newp, supportNew);
6001: #if defined(PETSC_USE_DEBUG)
6002: for (p = 0; p < 2; ++p) {
6003: 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);
6004: }
6005: #endif
6006: ++newp;
6007: /* Face {h, m, l, e} */
6008: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
6009: orntNew[0] = 0;
6010: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
6011: orntNew[1] = -2;
6012: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1);
6013: orntNew[2] = -2;
6014: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
6015: orntNew[3] = 0;
6016: DMPlexSetCone(rdm, newp, coneNew);
6017: DMPlexSetConeOrientation(rdm, newp, orntNew);
6018: #if defined(PETSC_USE_DEBUG)
6019: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6020: for (p = 0; p < 4; ++p) {
6021: 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);
6022: }
6023: #endif
6024: supportNew[0] = cStartNew + (c - cStart)*4 + 1;
6025: supportNew[1] = cStartNew + (c - cStart)*4 + 3;
6026: DMPlexSetSupport(rdm, newp, supportNew);
6027: #if defined(PETSC_USE_DEBUG)
6028: for (p = 0; p < 2; ++p) {
6029: 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);
6030: }
6031: #endif
6032: ++newp;
6033: /* Face {i, m, l, f} */
6034: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
6035: orntNew[0] = 0;
6036: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
6037: orntNew[1] = -2;
6038: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2);
6039: orntNew[2] = -2;
6040: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1);
6041: orntNew[3] = 0;
6042: DMPlexSetCone(rdm, newp, coneNew);
6043: DMPlexSetConeOrientation(rdm, newp, orntNew);
6044: #if defined(PETSC_USE_DEBUG)
6045: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6046: for (p = 0; p < 4; ++p) {
6047: 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);
6048: }
6049: #endif
6050: supportNew[0] = cStartNew + (c - cStart)*4 + 2;
6051: supportNew[1] = cStartNew + (c - cStart)*4 + 3;
6052: DMPlexSetSupport(rdm, newp, supportNew);
6053: #if defined(PETSC_USE_DEBUG)
6054: for (p = 0; p < 2; ++p) {
6055: 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);
6056: }
6057: #endif
6058: ++newp;
6059: }
6060: /* Hybrid split faces have 4 edges and same cells */
6061: for (f = fMax; f < fEnd; ++f) {
6062: const PetscInt *cone, *ornt, *support;
6063: PetscInt coneNew[4], orntNew[4];
6064: PetscInt size, s;
6065: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2;
6067: DMPlexGetCone(dm, f, &cone);
6068: #if defined(PETSC_USE_DEBUG)
6069: 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);
6070: 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);
6071: 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);
6072: 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);
6073: #endif
6074: DMPlexGetConeOrientation(dm, f, &ornt);
6075: /* A face */
6076: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
6077: orntNew[0] = ornt[0];
6078: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax);
6079: orntNew[1] = 0;
6080: coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
6081: orntNew[2] = ornt[1] < 0 ? 0 : -2;
6082: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[2] - eMax);
6083: orntNew[3] = ornt[2] < 0 ? 0 : -2;
6084: DMPlexSetCone(rdm, newp, coneNew);
6085: DMPlexSetConeOrientation(rdm, newp, orntNew);
6086: #if defined(PETSC_USE_DEBUG)
6087: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6088: for (p = 0; p < 4; ++p) {
6089: 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);
6090: }
6091: #endif
6093: /* B face */
6094: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
6095: orntNew[0] = ornt[0];
6096: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[3] - eMax);
6097: orntNew[1] = ornt[3];
6098: coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
6099: orntNew[2] = ornt[1] < 0 ? 0 : -2;
6100: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax);
6101: orntNew[3] = -2;
6102: DMPlexSetCone(rdm, newp+1, coneNew);
6103: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
6104: #if defined(PETSC_USE_DEBUG)
6105: 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);
6106: for (p = 0; p < 4; ++p) {
6107: 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);
6108: }
6109: #endif
6111: DMPlexGetSupportSize(dm, f, &size);
6112: DMPlexGetSupport(dm, f, &support);
6113: for (r = 0; r < 2; ++r) {
6114: for (s = 0; s < size; ++s) {
6115: const PetscInt *coneCell, *orntCell;
6116: PetscInt coneSize, o, of, c;
6118: DMPlexGetConeSize(dm, support[s], &coneSize);
6119: 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);
6120: DMPlexGetCone(dm, support[s], &coneCell);
6121: DMPlexGetConeOrientation(dm, support[s], &orntCell);
6122: o = orntCell[0] < 0 ? -1 : 1;
6123: o = 1;
6124: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
6125: 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);
6126: if (c == coneSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]);
6127: of = orntCell[c] < 0 ? -1 : 1;
6128: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + (c-2 + (o*of < 0 ? 1-r : r))%3;
6129: }
6130: DMPlexSetSupport(rdm, newp + r, supportRef);
6131: #if defined(PETSC_USE_DEBUG)
6132: for (p = 0; p < size; ++p) {
6133: 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);
6134: }
6135: #endif
6136: }
6137: }
6138: /* Interior hybrid faces have 4 edges and 2 cells */
6139: for (c = cMax; c < cEnd; ++c) {
6140: PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3;
6141: const PetscInt *cone, *ornt;
6142: PetscInt coneNew[4], orntNew[4];
6143: PetscInt supportNew[2];
6145: DMPlexGetCone(dm, c, &cone);
6146: #if defined(PETSC_USE_DEBUG)
6147: 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);
6148: 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);
6149: 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);
6150: 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);
6151: 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);
6152: #endif
6153: DMPlexGetConeOrientation(dm, c, &ornt);
6154: /* Face {a, g, h, d} */
6155: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
6156: orntNew[0] = 0;
6157: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6158: orntNew[1] = 0;
6159: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
6160: orntNew[2] = -2;
6161: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[2] - fMax);
6162: orntNew[3] = -2;
6163: DMPlexSetCone(rdm, newp, coneNew);
6164: DMPlexSetConeOrientation(rdm, newp, orntNew);
6165: #if defined(PETSC_USE_DEBUG)
6166: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6167: for (p = 0; p < 4; ++p) {
6168: 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);
6169: }
6170: #endif
6171: supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0;
6172: supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1;
6173: DMPlexSetSupport(rdm, newp, supportNew);
6174: #if defined(PETSC_USE_DEBUG)
6175: for (p = 0; p < 2; ++p) {
6176: 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);
6177: }
6178: #endif
6179: ++newp;
6180: /* Face {b, g, h, l} */
6181: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
6182: orntNew[0] = 0;
6183: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6184: orntNew[1] = 0;
6185: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
6186: orntNew[2] = -2;
6187: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[3] - fMax);
6188: orntNew[3] = -2;
6189: DMPlexSetCone(rdm, newp, coneNew);
6190: DMPlexSetConeOrientation(rdm, newp, orntNew);
6191: #if defined(PETSC_USE_DEBUG)
6192: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6193: for (p = 0; p < 4; ++p) {
6194: 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);
6195: }
6196: #endif
6197: supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1;
6198: supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2;
6199: DMPlexSetSupport(rdm, newp, supportNew);
6200: #if defined(PETSC_USE_DEBUG)
6201: for (p = 0; p < 2; ++p) {
6202: 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);
6203: }
6204: #endif
6205: ++newp;
6206: /* Face {c, g, h, f} */
6207: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
6208: orntNew[0] = 0;
6209: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6210: orntNew[1] = 0;
6211: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
6212: orntNew[2] = -2;
6213: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[4] - fMax);
6214: orntNew[3] = -2;
6215: DMPlexSetCone(rdm, newp, coneNew);
6216: DMPlexSetConeOrientation(rdm, newp, orntNew);
6217: #if defined(PETSC_USE_DEBUG)
6218: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6219: for (p = 0; p < 4; ++p) {
6220: 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);
6221: }
6222: #endif
6223: supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2;
6224: supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0;
6225: DMPlexSetSupport(rdm, newp, supportNew);
6226: #if defined(PETSC_USE_DEBUG)
6227: for (p = 0; p < 2; ++p) {
6228: 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);
6229: }
6230: #endif
6231: }
6232: /* Face edges have 2 vertices and 2 + cell faces supports */
6233: for (f = fStart; f < fMax; ++f) {
6234: const PetscInt *cone, *ornt, *support;
6235: PetscInt coneSize, supportSize, s;
6237: DMPlexGetSupportSize(dm, f, &supportSize);
6238: DMPlexGetSupport(dm, f, &support);
6239: for (r = 0; r < 3; ++r) {
6240: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
6241: PetscInt coneNew[2];
6242: PetscInt fint[4][3] = { {0, 1, 2},
6243: {3, 4, 0},
6244: {2, 5, 3},
6245: {1, 4, 5} };
6247: DMPlexGetCone(dm, f, &cone);
6248: 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);
6249: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
6250: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart;
6251: DMPlexSetCone(rdm, newp, coneNew);
6252: #if defined(PETSC_USE_DEBUG)
6253: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6254: for (p = 0; p < 2; ++p) {
6255: 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);
6256: }
6257: #endif
6258: supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3;
6259: supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3;
6260: for (s = 0; s < supportSize; ++s) {
6261: PetscInt er;
6263: supportRef[2+s] = -1;
6264: DMPlexGetConeSize(dm, support[s], &coneSize);
6265: 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);
6266: 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);
6267: DMPlexGetCone(dm, support[s], &cone);
6268: DMPlexGetConeOrientation(dm, support[s], &ornt);
6269: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
6270: er = GetTriInteriorEdgeInverse_Static(ornt[c], r);
6271: if (coneSize == 4) {
6272: supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (support[s] - cStart)*6 + fint[c][er];
6273: } else if (coneSize == 5) {
6274: 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);
6275: supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + er;
6276: }
6277: }
6278: DMPlexSetSupport(rdm, newp, supportRef);
6279: #if defined(PETSC_USE_DEBUG)
6280: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6281: for (p = 0; p < supportSize + 2; ++p) {
6282: 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);
6283: }
6284: #endif
6285: }
6286: }
6287: /* Interior cell edges have 2 vertices and 3 faces */
6288: for (c = cStart; c < cMax; ++c) {
6289: const PetscInt *cone;
6290: PetscInt fint[4][3] = { {0,1,2},
6291: {0,3,4},
6292: {2,3,5},
6293: {1,4,5} } ;
6295: DMPlexGetCone(dm, c, &cone);
6296: for (r = 0; r < 4; r++) {
6297: PetscInt coneNew[2], supportNew[3];
6298: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r;
6300: 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);
6301: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
6302: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax -fStart) + c - cStart;
6303: DMPlexSetCone(rdm, newp, coneNew);
6304: #if defined(PETSC_USE_DEBUG)
6305: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6306: for (p = 0; p < 2; ++p) {
6307: 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);
6308: }
6309: #endif
6310: supportNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][0];
6311: supportNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][1];
6312: supportNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][2];
6313: DMPlexSetSupport(rdm, newp, supportNew);
6314: #if defined(PETSC_USE_DEBUG)
6315: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6316: for (p = 0; p < 3; ++p) {
6317: 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);
6318: }
6319: #endif
6320: }
6321: }
6322: /* Hybrid edges have two vertices and the same faces */
6323: for (e = eMax; e < eEnd; ++e) {
6324: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax);
6325: const PetscInt *cone, *support, *fcone;
6326: PetscInt coneNew[2], size, fsize, s;
6328: DMPlexGetCone(dm, e, &cone);
6329: DMPlexGetSupportSize(dm, e, &size);
6330: DMPlexGetSupport(dm, e, &support);
6331: coneNew[0] = vStartNew + (cone[0] - vStart);
6332: coneNew[1] = vStartNew + (cone[1] - vStart);
6333: DMPlexSetCone(rdm, newp, coneNew);
6334: #if defined(PETSC_USE_DEBUG)
6335: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is a edge [%D, %D)", newp, eStartNew, eEndNew);
6336: for (p = 0; p < 2; ++p) {
6337: 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);
6338: }
6339: #endif
6340: for (s = 0; s < size; ++s) {
6341: DMPlexGetConeSize(dm, support[s], &fsize);
6342: DMPlexGetCone(dm, support[s], &fcone);
6343: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
6344: if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]);
6345: supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + c-2;
6346: }
6347: DMPlexSetSupport(rdm, newp, supportRef);
6348: #if defined(PETSC_USE_DEBUG)
6349: for (p = 0; p < size; ++p) {
6350: 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);
6351: }
6352: #endif
6353: }
6354: /* Hybrid face edges have 2 vertices and 2 + cell faces supports */
6355: for (f = fMax; f < fEnd; ++f) {
6356: const PetscInt *cone, *ornt, *support;
6357: PetscInt coneSize, supportSize;
6358: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + f - fMax;
6359: PetscInt coneNew[2], s;
6361: DMPlexGetCone(dm, f, &cone);
6362: #if defined(PETSC_USE_DEBUG)
6363: 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);
6364: 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);
6365: #endif
6366: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
6367: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
6368: DMPlexSetCone(rdm, newp, coneNew);
6369: #if defined(PETSC_USE_DEBUG)
6370: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6371: for (p = 0; p < 2; ++p) {
6372: 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);
6373: }
6374: #endif
6375: supportRef[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 0;
6376: supportRef[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 1;
6377: DMPlexGetSupportSize(dm, f, &supportSize);
6378: DMPlexGetSupport(dm, f, &support);
6379: for (s = 0; s < supportSize; ++s) {
6380: DMPlexGetConeSize(dm, support[s], &coneSize);
6381: 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);
6382: DMPlexGetCone(dm, support[s], &cone);
6383: DMPlexGetConeOrientation(dm, support[s], &ornt);
6384: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
6385: 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);
6386: supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c - 2;
6387: }
6388: DMPlexSetSupport(rdm, newp, supportRef);
6389: #if defined(PETSC_USE_DEBUG)
6390: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6391: for (p = 0; p < supportSize + 2; ++p) {
6392: 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);
6393: }
6394: #endif
6395: }
6396: /* Hybrid cell edges have 2 vertices and 3 faces */
6397: for (c = cMax; c < cEnd; ++c) {
6398: PetscInt coneNew[2], supportNew[3];
6399: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6400: const PetscInt *cone;
6402: DMPlexGetCone(dm, c, &cone);
6403: #if defined(PETSC_USE_DEBUG)
6404: 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);
6405: 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);
6406: #endif
6407: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
6408: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
6409: DMPlexSetCone(rdm, newp, coneNew);
6410: #if defined(PETSC_USE_DEBUG)
6411: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6412: for (p = 0; p < 2; ++p) {
6413: 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);
6414: }
6415: #endif
6416: supportNew[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
6417: supportNew[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
6418: supportNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
6419: DMPlexSetSupport(rdm, newp, supportNew);
6420: #if defined(PETSC_USE_DEBUG)
6421: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6422: for (p = 0; p < 3; ++p) {
6423: 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);
6424: }
6425: #endif
6426: }
6427: /* Old vertices have identical supports */
6428: for (v = vStart; v < vEnd; ++v) {
6429: const PetscInt newp = vStartNew + (v - vStart);
6430: const PetscInt *support, *cone;
6431: PetscInt size, s;
6433: DMPlexGetSupportSize(dm, v, &size);
6434: DMPlexGetSupport(dm, v, &support);
6435: for (s = 0; s < size; ++s) {
6436: const PetscInt e = support[s];
6438: supportRef[s] = -1;
6439: if (eStart <= e) {
6440: if (e < eMax) {
6441: DMPlexGetCone(dm, e, &cone);
6442: supportRef[s] = eStartNew + (e - eStart)*2 + (cone[1] == v ? 1 : 0);
6443: } else if (e < eEnd) {
6444: supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + e - eMax;
6445: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd);
6446: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd);
6447: }
6448: DMPlexSetSupport(rdm, newp, supportRef);
6449: #if defined(PETSC_USE_DEBUG)
6450: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6451: for (p = 0; p < size; ++p) {
6452: 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);
6453: }
6454: #endif
6455: }
6456: /* Interior edge vertices have 2 + faces supports */
6457: for (e = eStart; e < eMax; ++e) {
6458: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
6459: const PetscInt *cone, *support;
6460: PetscInt size, s;
6462: DMPlexGetSupportSize(dm, e, &size);
6463: DMPlexGetSupport(dm, e, &support);
6464: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
6465: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
6466: for (s = 0; s < size; ++s) {
6467: PetscInt r, coneSize;
6469: supportRef[2+s] = -1;
6470: DMPlexGetConeSize(dm, support[s], &coneSize);
6471: 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);
6472: 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);
6473: DMPlexGetCone(dm, support[s], &cone);
6474: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
6475: if (coneSize == 3) supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + r;
6476: else if (coneSize == 4) {
6477: 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);
6478: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + support[s] - fMax;
6479: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax);
6480: }
6481: DMPlexSetSupport(rdm, newp, supportRef);
6482: #if defined(PETSC_USE_DEBUG)
6483: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6484: for (p = 0; p < 2+size; ++p) {
6485: 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);
6486: }
6487: #endif
6488: }
6489: /* Split Edges have 2 vertices and the same faces as the parent */
6490: for (e = eStart; e < eMax; ++e) {
6491: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
6493: for (r = 0; r < 2; ++r) {
6494: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
6495: const PetscInt *cone, *ornt, *support;
6496: PetscInt coneNew[2], coneSize, c, supportSize, s;
6498: DMPlexGetCone(dm, e, &cone);
6499: coneNew[0] = vStartNew + (cone[0] - vStart);
6500: coneNew[1] = vStartNew + (cone[1] - vStart);
6501: coneNew[(r+1)%2] = newv;
6502: DMPlexSetCone(rdm, newp, coneNew);
6503: #if defined(PETSC_USE_DEBUG)
6504: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6505: for (p = 0; p < 2; ++p) {
6506: 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);
6507: }
6508: #endif
6509: DMPlexGetSupportSize(dm, e, &supportSize);
6510: DMPlexGetSupport(dm, e, &support);
6511: for (s = 0; s < supportSize; ++s) {
6512: DMPlexGetConeSize(dm, support[s], &coneSize);
6513: 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);
6514: 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);
6515: DMPlexGetCone(dm, support[s], &cone);
6516: DMPlexGetConeOrientation(dm, support[s], &ornt);
6517: for (c = 0; c < coneSize; ++c) {
6518: if (cone[c] == e) break;
6519: }
6520: if (coneSize == 3) supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3;
6521: else if (coneSize == 4) {
6522: 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);
6523: supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
6524: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax);
6525: }
6526: DMPlexSetSupport(rdm, newp, supportRef);
6527: #if defined(PETSC_USE_DEBUG)
6528: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6529: for (p = 0; p < supportSize; ++p) {
6530: 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);
6531: }
6532: #endif
6533: }
6534: }
6535: /* Face vertices have 3 + cells supports */
6536: for (f = fStart; f < fMax; ++f) {
6537: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
6538: const PetscInt *cone, *support;
6539: PetscInt size, s;
6541: DMPlexGetSupportSize(dm, f, &size);
6542: DMPlexGetSupport(dm, f, &support);
6543: supportRef[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
6544: supportRef[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
6545: supportRef[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
6546: for (s = 0; s < size; ++s) {
6547: PetscInt r, coneSize;
6549: supportRef[3+s] = -1;
6550: DMPlexGetConeSize(dm, support[s], &coneSize);
6551: 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);
6552: 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);
6553: DMPlexGetCone(dm, support[s], &cone);
6554: for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;}
6555: if (coneSize == 4) supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (support[s] - cStart)*4 + r;
6556: else if (coneSize == 5) {
6557: 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);
6558: supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + support[s] - cMax;
6559: }
6560: }
6561: DMPlexSetSupport(rdm, newp, supportRef);
6562: #if defined(PETSC_USE_DEBUG)
6563: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6564: for (p = 0; p < 3+size; ++p) {
6565: 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);
6566: }
6567: #endif
6568: }
6569: /* Interior cell vertices have 4 supports */
6570: for (c = cStart; c < cMax; ++c) {
6571: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart;
6573: supportRef[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
6574: supportRef[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
6575: supportRef[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
6576: supportRef[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
6577: DMPlexSetSupport(rdm, newp, supportRef);
6578: #if defined(PETSC_USE_DEBUG)
6579: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6580: for (p = 0; p < 4; ++p) {
6581: 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);
6582: }
6583: #endif
6584: }
6585: PetscFree(supportRef);
6586: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
6587: break;
6588: case REFINER_HEX_3D:
6589: /*
6590: Bottom (viewed from top) Top
6591: 1---------2---------2 7---------2---------6
6592: | | | | | |
6593: | B 2 C | | H 2 G |
6594: | | | | | |
6595: 3----3----0----1----1 3----3----0----1----1
6596: | | | | | |
6597: | A 0 D | | E 0 F |
6598: | | | | | |
6599: 0---------0---------3 4---------0---------5
6600: */
6601: /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
6602: for (c = cStart; c < cEnd; ++c) {
6603: const PetscInt newp = (c - cStart)*8;
6604: const PetscInt *cone, *ornt;
6605: PetscInt coneNew[6], orntNew[6];
6607: DMPlexGetCone(dm, c, &cone);
6608: DMPlexGetConeOrientation(dm, c, &ornt);
6609: /* A hex */
6610: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
6611: orntNew[0] = ornt[0];
6612: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */
6613: orntNew[1] = 0;
6614: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
6615: orntNew[2] = ornt[2];
6616: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */
6617: orntNew[3] = 0;
6618: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */
6619: orntNew[4] = 0;
6620: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
6621: orntNew[5] = ornt[5];
6622: DMPlexSetCone(rdm, newp+0, coneNew);
6623: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
6624: #if defined(PETSC_USE_DEBUG)
6625: 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);
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: /* B hex */
6631: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
6632: orntNew[0] = ornt[0];
6633: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */
6634: orntNew[1] = 0;
6635: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */
6636: orntNew[2] = -1;
6637: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
6638: orntNew[3] = ornt[3];
6639: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */
6640: orntNew[4] = 0;
6641: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
6642: orntNew[5] = ornt[5];
6643: DMPlexSetCone(rdm, newp+1, coneNew);
6644: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
6645: #if defined(PETSC_USE_DEBUG)
6646: 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);
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: /* C hex */
6652: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
6653: orntNew[0] = ornt[0];
6654: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */
6655: orntNew[1] = 0;
6656: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */
6657: orntNew[2] = -1;
6658: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
6659: orntNew[3] = ornt[3];
6660: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
6661: orntNew[4] = ornt[4];
6662: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */
6663: orntNew[5] = -4;
6664: DMPlexSetCone(rdm, newp+2, coneNew);
6665: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
6666: #if defined(PETSC_USE_DEBUG)
6667: 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);
6668: for (p = 0; p < 6; ++p) {
6669: 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);
6670: }
6671: #endif
6672: /* D hex */
6673: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
6674: orntNew[0] = ornt[0];
6675: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */
6676: orntNew[1] = 0;
6677: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
6678: orntNew[2] = ornt[2];
6679: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */
6680: orntNew[3] = 0;
6681: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
6682: orntNew[4] = ornt[4];
6683: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */
6684: orntNew[5] = -4;
6685: DMPlexSetCone(rdm, newp+3, coneNew);
6686: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
6687: #if defined(PETSC_USE_DEBUG)
6688: 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);
6689: for (p = 0; p < 6; ++p) {
6690: 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);
6691: }
6692: #endif
6693: /* E hex */
6694: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */
6695: orntNew[0] = -4;
6696: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
6697: orntNew[1] = ornt[1];
6698: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
6699: orntNew[2] = ornt[2];
6700: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */
6701: orntNew[3] = 0;
6702: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */
6703: orntNew[4] = -1;
6704: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
6705: orntNew[5] = ornt[5];
6706: DMPlexSetCone(rdm, newp+4, coneNew);
6707: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
6708: #if defined(PETSC_USE_DEBUG)
6709: 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);
6710: for (p = 0; p < 6; ++p) {
6711: 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);
6712: }
6713: #endif
6714: /* F hex */
6715: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */
6716: orntNew[0] = -4;
6717: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
6718: orntNew[1] = ornt[1];
6719: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
6720: orntNew[2] = ornt[2];
6721: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */
6722: orntNew[3] = -1;
6723: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
6724: orntNew[4] = ornt[4];
6725: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */
6726: orntNew[5] = 1;
6727: DMPlexSetCone(rdm, newp+5, coneNew);
6728: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
6729: #if defined(PETSC_USE_DEBUG)
6730: 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);
6731: for (p = 0; p < 6; ++p) {
6732: 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);
6733: }
6734: #endif
6735: /* G hex */
6736: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */
6737: orntNew[0] = -4;
6738: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
6739: orntNew[1] = ornt[1];
6740: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */
6741: orntNew[2] = 0;
6742: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
6743: orntNew[3] = ornt[3];
6744: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
6745: orntNew[4] = ornt[4];
6746: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */
6747: orntNew[5] = -3;
6748: DMPlexSetCone(rdm, newp+6, coneNew);
6749: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
6750: #if defined(PETSC_USE_DEBUG)
6751: 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);
6752: for (p = 0; p < 6; ++p) {
6753: 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);
6754: }
6755: #endif
6756: /* H hex */
6757: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */
6758: orntNew[0] = -4;
6759: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
6760: orntNew[1] = ornt[1];
6761: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */
6762: orntNew[2] = -1;
6763: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
6764: orntNew[3] = ornt[3];
6765: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */
6766: orntNew[4] = 3;
6767: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
6768: orntNew[5] = ornt[5];
6769: DMPlexSetCone(rdm, newp+7, coneNew);
6770: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
6771: #if defined(PETSC_USE_DEBUG)
6772: 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);
6773: for (p = 0; p < 6; ++p) {
6774: 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);
6775: }
6776: #endif
6777: }
6778: /* Split faces have 4 edges and the same cells as the parent */
6779: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
6780: PetscMalloc1(4 + maxSupportSize*2, &supportRef);
6781: for (f = fStart; f < fEnd; ++f) {
6782: for (r = 0; r < 4; ++r) {
6783: /* TODO: This can come from GetFaces_Internal() */
6784: 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};
6785: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
6786: const PetscInt *cone, *ornt, *support;
6787: PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s;
6789: DMPlexGetCone(dm, f, &cone);
6790: DMPlexGetConeOrientation(dm, f, &ornt);
6791: coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
6792: orntNew[(r+3)%4] = ornt[(r+3)%4];
6793: coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
6794: orntNew[(r+0)%4] = ornt[r];
6795: coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
6796: orntNew[(r+1)%4] = 0;
6797: coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
6798: orntNew[(r+2)%4] = -2;
6799: DMPlexSetCone(rdm, newp, coneNew);
6800: DMPlexSetConeOrientation(rdm, newp, orntNew);
6801: #if defined(PETSC_USE_DEBUG)
6802: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6803: for (p = 0; p < 4; ++p) {
6804: 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);
6805: }
6806: #endif
6807: DMPlexGetSupportSize(dm, f, &supportSize);
6808: DMPlexGetSupport(dm, f, &support);
6809: for (s = 0; s < supportSize; ++s) {
6810: DMPlexGetConeSize(dm, support[s], &coneSize);
6811: DMPlexGetCone(dm, support[s], &cone);
6812: DMPlexGetConeOrientation(dm, support[s], &ornt);
6813: for (c = 0; c < coneSize; ++c) {
6814: if (cone[c] == f) break;
6815: }
6816: supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
6817: }
6818: DMPlexSetSupport(rdm, newp, supportRef);
6819: #if defined(PETSC_USE_DEBUG)
6820: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6821: for (p = 0; p < supportSize; ++p) {
6822: 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);
6823: }
6824: #endif
6825: }
6826: }
6827: /* Interior faces have 4 edges and 2 cells */
6828: for (c = cStart; c < cEnd; ++c) {
6829: 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};
6830: const PetscInt *cone, *ornt;
6831: PetscInt newp, coneNew[4], orntNew[4], supportNew[2];
6833: DMPlexGetCone(dm, c, &cone);
6834: DMPlexGetConeOrientation(dm, c, &ornt);
6835: /* A-D face */
6836: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
6837: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
6838: orntNew[0] = 0;
6839: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6840: orntNew[1] = 0;
6841: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
6842: orntNew[2] = -2;
6843: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
6844: orntNew[3] = -2;
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: /* C-D face */
6854: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
6855: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
6856: orntNew[0] = 0;
6857: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6858: orntNew[1] = 0;
6859: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
6860: orntNew[2] = -2;
6861: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 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: /* B-C face */
6872: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
6873: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
6874: orntNew[0] = -2;
6875: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
6876: orntNew[1] = 0;
6877: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
6878: orntNew[2] = 0;
6879: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
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: /* A-B face */
6890: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
6891: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
6892: orntNew[0] = -2;
6893: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
6894: orntNew[1] = 0;
6895: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
6896: orntNew[2] = 0;
6897: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6898: orntNew[3] = -2;
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: /* E-F face */
6908: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
6909: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
6910: orntNew[0] = -2;
6911: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
6912: orntNew[1] = -2;
6913: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
6914: orntNew[2] = 0;
6915: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
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: /* F-G face */
6926: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
6927: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
6928: orntNew[0] = -2;
6929: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
6930: orntNew[1] = -2;
6931: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
6932: orntNew[2] = 0;
6933: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6934: orntNew[3] = 0;
6935: DMPlexSetCone(rdm, newp, coneNew);
6936: DMPlexSetConeOrientation(rdm, newp, orntNew);
6937: #if defined(PETSC_USE_DEBUG)
6938: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6939: for (p = 0; p < 4; ++p) {
6940: 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);
6941: }
6942: #endif
6943: /* G-H face */
6944: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
6945: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
6946: orntNew[0] = -2;
6947: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
6948: orntNew[1] = 0;
6949: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6950: orntNew[2] = 0;
6951: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
6952: orntNew[3] = -2;
6953: DMPlexSetCone(rdm, newp, coneNew);
6954: DMPlexSetConeOrientation(rdm, newp, orntNew);
6955: #if defined(PETSC_USE_DEBUG)
6956: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6957: for (p = 0; p < 4; ++p) {
6958: 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);
6959: }
6960: #endif
6961: /* E-H face */
6962: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
6963: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
6964: orntNew[0] = -2;
6965: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
6966: orntNew[1] = -2;
6967: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
6968: orntNew[2] = 0;
6969: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6970: orntNew[3] = 0;
6971: DMPlexSetCone(rdm, newp, coneNew);
6972: DMPlexSetConeOrientation(rdm, newp, orntNew);
6973: #if defined(PETSC_USE_DEBUG)
6974: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6975: for (p = 0; p < 4; ++p) {
6976: 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);
6977: }
6978: #endif
6979: /* A-E face */
6980: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
6981: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
6982: orntNew[0] = 0;
6983: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
6984: orntNew[1] = 0;
6985: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
6986: orntNew[2] = -2;
6987: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
6988: orntNew[3] = -2;
6989: DMPlexSetCone(rdm, newp, coneNew);
6990: DMPlexSetConeOrientation(rdm, newp, orntNew);
6991: #if defined(PETSC_USE_DEBUG)
6992: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6993: for (p = 0; p < 4; ++p) {
6994: 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);
6995: }
6996: #endif
6997: /* D-F face */
6998: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
6999: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
7000: orntNew[0] = -2;
7001: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
7002: orntNew[1] = 0;
7003: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
7004: orntNew[2] = 0;
7005: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
7006: orntNew[3] = -2;
7007: DMPlexSetCone(rdm, newp, coneNew);
7008: DMPlexSetConeOrientation(rdm, newp, orntNew);
7009: #if defined(PETSC_USE_DEBUG)
7010: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
7011: for (p = 0; p < 4; ++p) {
7012: 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);
7013: }
7014: #endif
7015: /* C-G face */
7016: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
7017: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
7018: orntNew[0] = -2;
7019: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
7020: orntNew[1] = -2;
7021: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
7022: orntNew[2] = 0;
7023: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
7024: orntNew[3] = 0;
7025: DMPlexSetCone(rdm, newp, coneNew);
7026: DMPlexSetConeOrientation(rdm, newp, orntNew);
7027: #if defined(PETSC_USE_DEBUG)
7028: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
7029: for (p = 0; p < 4; ++p) {
7030: 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);
7031: }
7032: #endif
7033: /* B-H face */
7034: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
7035: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
7036: orntNew[0] = 0;
7037: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
7038: orntNew[1] = -2;
7039: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
7040: orntNew[2] = -2;
7041: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
7042: orntNew[3] = 0;
7043: DMPlexSetCone(rdm, newp, coneNew);
7044: DMPlexSetConeOrientation(rdm, newp, orntNew);
7045: #if defined(PETSC_USE_DEBUG)
7046: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
7047: for (p = 0; p < 4; ++p) {
7048: 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);
7049: }
7050: #endif
7051: for (r = 0; r < 12; ++r) {
7052: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
7053: supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
7054: supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
7055: DMPlexSetSupport(rdm, newp, supportNew);
7056: #if defined(PETSC_USE_DEBUG)
7057: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
7058: for (p = 0; p < 2; ++p) {
7059: 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);
7060: }
7061: #endif
7062: }
7063: }
7064: /* Split edges have 2 vertices and the same faces as the parent */
7065: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
7066: for (e = eStart; e < eEnd; ++e) {
7067: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
7069: for (r = 0; r < 2; ++r) {
7070: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
7071: const PetscInt *cone, *ornt, *support;
7072: PetscInt coneNew[2], coneSize, c, supportSize, s;
7074: DMPlexGetCone(dm, e, &cone);
7075: coneNew[0] = vStartNew + (cone[0] - vStart);
7076: coneNew[1] = vStartNew + (cone[1] - vStart);
7077: coneNew[(r+1)%2] = newv;
7078: DMPlexSetCone(rdm, newp, coneNew);
7079: #if defined(PETSC_USE_DEBUG)
7080: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7081: for (p = 0; p < 2; ++p) {
7082: 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);
7083: }
7084: #endif
7085: DMPlexGetSupportSize(dm, e, &supportSize);
7086: DMPlexGetSupport(dm, e, &support);
7087: for (s = 0; s < supportSize; ++s) {
7088: DMPlexGetConeSize(dm, support[s], &coneSize);
7089: DMPlexGetCone(dm, support[s], &cone);
7090: DMPlexGetConeOrientation(dm, support[s], &ornt);
7091: for (c = 0; c < coneSize; ++c) {
7092: if (cone[c] == e) break;
7093: }
7094: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
7095: }
7096: DMPlexSetSupport(rdm, newp, supportRef);
7097: #if defined(PETSC_USE_DEBUG)
7098: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7099: for (p = 0; p < supportSize; ++p) {
7100: 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);
7101: }
7102: #endif
7103: }
7104: }
7105: /* Face edges have 2 vertices and 2+cells faces */
7106: for (f = fStart; f < fEnd; ++f) {
7107: 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};
7108: const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
7109: const PetscInt *cone, *coneCell, *orntCell, *support;
7110: PetscInt coneNew[2], coneSize, c, supportSize, s;
7112: DMPlexGetCone(dm, f, &cone);
7113: for (r = 0; r < 4; ++r) {
7114: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
7116: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
7117: coneNew[1] = newv;
7118: DMPlexSetCone(rdm, newp, coneNew);
7119: #if defined(PETSC_USE_DEBUG)
7120: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7121: for (p = 0; p < 2; ++p) {
7122: 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);
7123: }
7124: #endif
7125: DMPlexGetSupportSize(dm, f, &supportSize);
7126: DMPlexGetSupport(dm, f, &support);
7127: supportRef[0] = fStartNew + (f - fStart)*4 + r;
7128: supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
7129: for (s = 0; s < supportSize; ++s) {
7130: DMPlexGetConeSize(dm, support[s], &coneSize);
7131: DMPlexGetCone(dm, support[s], &coneCell);
7132: DMPlexGetConeOrientation(dm, support[s], &orntCell);
7133: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
7134: supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
7135: }
7136: DMPlexSetSupport(rdm, newp, supportRef);
7137: #if defined(PETSC_USE_DEBUG)
7138: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7139: for (p = 0; p < 2+supportSize; ++p) {
7140: 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);
7141: }
7142: #endif
7143: }
7144: }
7145: /* Cell edges have 2 vertices and 4 faces */
7146: for (c = cStart; c < cEnd; ++c) {
7147: 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};
7148: const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
7149: const PetscInt *cone;
7150: PetscInt coneNew[2], supportNew[4];
7152: DMPlexGetCone(dm, c, &cone);
7153: for (r = 0; r < 6; ++r) {
7154: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
7156: coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
7157: coneNew[1] = newv;
7158: DMPlexSetCone(rdm, newp, coneNew);
7159: #if defined(PETSC_USE_DEBUG)
7160: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7161: for (p = 0; p < 2; ++p) {
7162: 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);
7163: }
7164: #endif
7165: for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
7166: DMPlexSetSupport(rdm, newp, supportNew);
7167: #if defined(PETSC_USE_DEBUG)
7168: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7169: for (p = 0; p < 4; ++p) {
7170: 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);
7171: }
7172: #endif
7173: }
7174: }
7175: /* Old vertices have identical supports */
7176: for (v = vStart; v < vEnd; ++v) {
7177: const PetscInt newp = vStartNew + (v - vStart);
7178: const PetscInt *support, *cone;
7179: PetscInt size, s;
7181: DMPlexGetSupportSize(dm, v, &size);
7182: DMPlexGetSupport(dm, v, &support);
7183: for (s = 0; s < size; ++s) {
7184: PetscInt r = 0;
7186: DMPlexGetCone(dm, support[s], &cone);
7187: if (cone[1] == v) r = 1;
7188: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
7189: }
7190: DMPlexSetSupport(rdm, newp, supportRef);
7191: #if defined(PETSC_USE_DEBUG)
7192: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
7193: for (p = 0; p < size; ++p) {
7194: 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);
7195: }
7196: #endif
7197: }
7198: /* Edge vertices have 2 + faces supports */
7199: for (e = eStart; e < eEnd; ++e) {
7200: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
7201: const PetscInt *cone, *support;
7202: PetscInt size, s;
7204: DMPlexGetSupportSize(dm, e, &size);
7205: DMPlexGetSupport(dm, e, &support);
7206: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
7207: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
7208: for (s = 0; s < size; ++s) {
7209: PetscInt r;
7211: DMPlexGetCone(dm, support[s], &cone);
7212: for (r = 0; r < 4; ++r) if (cone[r] == e) break;
7213: supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
7214: }
7215: DMPlexSetSupport(rdm, newp, supportRef);
7216: #if defined(PETSC_USE_DEBUG)
7217: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
7218: for (p = 0; p < 2+size; ++p) {
7219: 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);
7220: }
7221: #endif
7222: }
7223: /* Face vertices have 4 + cells supports */
7224: for (f = fStart; f < fEnd; ++f) {
7225: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
7226: const PetscInt *cone, *support;
7227: PetscInt size, s;
7229: DMPlexGetSupportSize(dm, f, &size);
7230: DMPlexGetSupport(dm, f, &support);
7231: for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
7232: for (s = 0; s < size; ++s) {
7233: PetscInt r;
7235: DMPlexGetCone(dm, support[s], &cone);
7236: for (r = 0; r < 6; ++r) if (cone[r] == f) break;
7237: supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
7238: }
7239: DMPlexSetSupport(rdm, newp, supportRef);
7240: #if defined(PETSC_USE_DEBUG)
7241: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
7242: for (p = 0; p < 4+size; ++p) {
7243: 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);
7244: }
7245: #endif
7246: }
7247: /* Cell vertices have 6 supports */
7248: for (c = cStart; c < cEnd; ++c) {
7249: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
7250: PetscInt supportNew[6];
7252: for (r = 0; r < 6; ++r) {
7253: supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
7254: }
7255: DMPlexSetSupport(rdm, newp, supportNew);
7256: }
7257: PetscFree(supportRef);
7258: break;
7259: case REFINER_HYBRID_HEX_3D:
7260: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);
7261: /*
7262: Bottom (viewed from top) Top
7263: 1---------2---------2 7---------2---------6
7264: | | | | | |
7265: | B 2 C | | H 2 G |
7266: | | | | | |
7267: 3----3----0----1----1 3----3----0----1----1
7268: | | | | | |
7269: | A 0 D | | E 0 F |
7270: | | | | | |
7271: 0---------0---------3 4---------0---------5
7272: */
7273: /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
7274: for (c = cStart; c < cMax; ++c) {
7275: const PetscInt newp = (c - cStart)*8;
7276: const PetscInt *cone, *ornt;
7277: PetscInt coneNew[6], orntNew[6];
7279: DMPlexGetCone(dm, c, &cone);
7280: DMPlexGetConeOrientation(dm, c, &ornt);
7281: /* A hex */
7282: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
7283: orntNew[0] = ornt[0];
7284: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */
7285: orntNew[1] = 0;
7286: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
7287: orntNew[2] = ornt[2];
7288: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */
7289: orntNew[3] = 0;
7290: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */
7291: orntNew[4] = 0;
7292: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
7293: orntNew[5] = ornt[5];
7294: DMPlexSetCone(rdm, newp+0, coneNew);
7295: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
7296: #if defined(PETSC_USE_DEBUG)
7297: 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);
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: /* B hex */
7303: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
7304: orntNew[0] = ornt[0];
7305: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */
7306: orntNew[1] = 0;
7307: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */
7308: orntNew[2] = -1;
7309: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
7310: orntNew[3] = ornt[3];
7311: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */
7312: orntNew[4] = 0;
7313: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
7314: orntNew[5] = ornt[5];
7315: DMPlexSetCone(rdm, newp+1, coneNew);
7316: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
7317: #if defined(PETSC_USE_DEBUG)
7318: 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);
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: /* C hex */
7324: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
7325: orntNew[0] = ornt[0];
7326: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */
7327: orntNew[1] = 0;
7328: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */
7329: orntNew[2] = -1;
7330: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
7331: orntNew[3] = ornt[3];
7332: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
7333: orntNew[4] = ornt[4];
7334: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */
7335: orntNew[5] = -4;
7336: DMPlexSetCone(rdm, newp+2, coneNew);
7337: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
7338: #if defined(PETSC_USE_DEBUG)
7339: 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);
7340: for (p = 0; p < 6; ++p) {
7341: 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);
7342: }
7343: #endif
7344: /* D hex */
7345: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
7346: orntNew[0] = ornt[0];
7347: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */
7348: orntNew[1] = 0;
7349: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
7350: orntNew[2] = ornt[2];
7351: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */
7352: orntNew[3] = 0;
7353: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
7354: orntNew[4] = ornt[4];
7355: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */
7356: orntNew[5] = -4;
7357: DMPlexSetCone(rdm, newp+3, coneNew);
7358: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
7359: #if defined(PETSC_USE_DEBUG)
7360: 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);
7361: for (p = 0; p < 6; ++p) {
7362: 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);
7363: }
7364: #endif
7365: /* E hex */
7366: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */
7367: orntNew[0] = -4;
7368: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
7369: orntNew[1] = ornt[1];
7370: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
7371: orntNew[2] = ornt[2];
7372: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */
7373: orntNew[3] = 0;
7374: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */
7375: orntNew[4] = -1;
7376: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
7377: orntNew[5] = ornt[5];
7378: DMPlexSetCone(rdm, newp+4, coneNew);
7379: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
7380: #if defined(PETSC_USE_DEBUG)
7381: 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);
7382: for (p = 0; p < 6; ++p) {
7383: 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);
7384: }
7385: #endif
7386: /* F hex */
7387: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */
7388: orntNew[0] = -4;
7389: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
7390: orntNew[1] = ornt[1];
7391: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
7392: orntNew[2] = ornt[2];
7393: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */
7394: orntNew[3] = -1;
7395: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
7396: orntNew[4] = ornt[4];
7397: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */
7398: orntNew[5] = 1;
7399: DMPlexSetCone(rdm, newp+5, coneNew);
7400: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
7401: #if defined(PETSC_USE_DEBUG)
7402: 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);
7403: for (p = 0; p < 6; ++p) {
7404: 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);
7405: }
7406: #endif
7407: /* G hex */
7408: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */
7409: orntNew[0] = -4;
7410: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
7411: orntNew[1] = ornt[1];
7412: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */
7413: orntNew[2] = 0;
7414: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
7415: orntNew[3] = ornt[3];
7416: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
7417: orntNew[4] = ornt[4];
7418: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */
7419: orntNew[5] = -3;
7420: DMPlexSetCone(rdm, newp+6, coneNew);
7421: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
7422: #if defined(PETSC_USE_DEBUG)
7423: 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);
7424: for (p = 0; p < 6; ++p) {
7425: 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);
7426: }
7427: #endif
7428: /* H hex */
7429: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */
7430: orntNew[0] = -4;
7431: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
7432: orntNew[1] = ornt[1];
7433: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */
7434: orntNew[2] = -1;
7435: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
7436: orntNew[3] = ornt[3];
7437: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */
7438: orntNew[4] = 3;
7439: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
7440: orntNew[5] = ornt[5];
7441: DMPlexSetCone(rdm, newp+7, coneNew);
7442: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
7443: #if defined(PETSC_USE_DEBUG)
7444: 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);
7445: for (p = 0; p < 6; ++p) {
7446: 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);
7447: }
7448: #endif
7449: }
7450: /* Hybrid cells have 6 faces: Front, Back, Sides */
7451: /*
7452: 3---------2---------2
7453: | | |
7454: | D 2 C |
7455: | | |
7456: 3----3----0----1----1
7457: | | |
7458: | A 0 B |
7459: | | |
7460: 0---------0---------1
7461: */
7462: for (c = cMax; c < cEnd; ++c) {
7463: const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4;
7464: const PetscInt *cone, *ornt, *fornt;
7465: PetscInt coneNew[6], orntNew[6], o, of, i;
7467: DMPlexGetCone(dm, c, &cone);
7468: DMPlexGetConeOrientation(dm, c, &ornt);
7469: DMPlexGetConeOrientation(dm, cone[0], &fornt);
7470: o = ornt[0] < 0 ? -1 : 1;
7471: for (r = 0; r < 4; ++r) {
7472: PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
7473: PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
7474: PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
7475: 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]);
7476: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA;
7477: orntNew[0] = ornt[0];
7478: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA;
7479: orntNew[1] = ornt[0];
7480: of = fornt[edgeA] < 0 ? -1 : 1;
7481: i = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
7482: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
7483: orntNew[i] = ornt[edgeA];
7484: i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
7485: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA;
7486: orntNew[i] = 0;
7487: i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
7488: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB;
7489: orntNew[i] = -2;
7490: of = fornt[edgeB] < 0 ? -1 : 1;
7491: i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
7492: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
7493: orntNew[i] = ornt[edgeB];
7494: DMPlexSetCone(rdm, newp+r, coneNew);
7495: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
7496: #if defined(PETSC_USE_DEBUG)
7497: 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);
7498: for (p = 0; p < 2; ++p) {
7499: 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);
7500: }
7501: for (p = 2; p < 6; ++p) {
7502: 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);
7503: }
7504: #endif
7505: }
7506: }
7507: /* Interior split faces have 4 edges and the same cells as the parent */
7508: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
7509: PetscMalloc1(4 + maxSupportSize*2, &supportRef);
7510: for (f = fStart; f < fMax; ++f) {
7511: for (r = 0; r < 4; ++r) {
7512: /* TODO: This can come from GetFaces_Internal() */
7513: 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};
7514: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
7515: const PetscInt *cone, *ornt, *support;
7516: PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s;
7518: DMPlexGetCone(dm, f, &cone);
7519: DMPlexGetConeOrientation(dm, f, &ornt);
7520: coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
7521: orntNew[(r+3)%4] = ornt[(r+3)%4];
7522: coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
7523: orntNew[(r+0)%4] = ornt[r];
7524: coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
7525: orntNew[(r+1)%4] = 0;
7526: coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
7527: orntNew[(r+2)%4] = -2;
7528: DMPlexSetCone(rdm, newp, coneNew);
7529: DMPlexSetConeOrientation(rdm, newp, orntNew);
7530: #if defined(PETSC_USE_DEBUG)
7531: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7532: for (p = 0; p < 4; ++p) {
7533: 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);
7534: }
7535: #endif
7536: DMPlexGetSupportSize(dm, f, &supportSize);
7537: DMPlexGetSupport(dm, f, &support);
7538: for (s = 0; s < supportSize; ++s) {
7539: PetscInt subf;
7540: DMPlexGetConeSize(dm, support[s], &coneSize);
7541: DMPlexGetCone(dm, support[s], &cone);
7542: DMPlexGetConeOrientation(dm, support[s], &ornt);
7543: for (c = 0; c < coneSize; ++c) {
7544: if (cone[c] == f) break;
7545: }
7546: subf = GetQuadSubfaceInverse_Static(ornt[c], r);
7547: if (support[s] < cMax) {
7548: supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
7549: } else {
7550: supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf;
7551: }
7552: }
7553: DMPlexSetSupport(rdm, newp, supportRef);
7554: #if defined(PETSC_USE_DEBUG)
7555: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7556: for (p = 0; p < supportSize; ++p) {
7557: 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);
7558: }
7559: #endif
7560: }
7561: }
7562: /* Interior cell faces have 4 edges and 2 cells */
7563: for (c = cStart; c < cMax; ++c) {
7564: 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};
7565: const PetscInt *cone, *ornt;
7566: PetscInt newp, coneNew[4], orntNew[4], supportNew[2];
7568: DMPlexGetCone(dm, c, &cone);
7569: DMPlexGetConeOrientation(dm, c, &ornt);
7570: /* A-D face */
7571: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
7572: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
7573: orntNew[0] = 0;
7574: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7575: orntNew[1] = 0;
7576: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7577: orntNew[2] = -2;
7578: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
7579: orntNew[3] = -2;
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: /* C-D face */
7589: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
7590: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
7591: orntNew[0] = 0;
7592: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7593: orntNew[1] = 0;
7594: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7595: orntNew[2] = -2;
7596: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 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: /* B-C face */
7607: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
7608: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
7609: orntNew[0] = -2;
7610: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
7611: orntNew[1] = 0;
7612: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7613: orntNew[2] = 0;
7614: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
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: /* A-B face */
7625: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
7626: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
7627: orntNew[0] = -2;
7628: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
7629: orntNew[1] = 0;
7630: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7631: orntNew[2] = 0;
7632: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7633: orntNew[3] = -2;
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: /* E-F face */
7643: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
7644: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7645: orntNew[0] = -2;
7646: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
7647: orntNew[1] = -2;
7648: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
7649: orntNew[2] = 0;
7650: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
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: /* F-G face */
7661: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
7662: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7663: orntNew[0] = -2;
7664: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
7665: orntNew[1] = -2;
7666: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
7667: orntNew[2] = 0;
7668: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7669: orntNew[3] = 0;
7670: DMPlexSetCone(rdm, newp, coneNew);
7671: DMPlexSetConeOrientation(rdm, newp, orntNew);
7672: #if defined(PETSC_USE_DEBUG)
7673: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7674: for (p = 0; p < 4; ++p) {
7675: 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);
7676: }
7677: #endif
7678: /* G-H face */
7679: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
7680: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
7681: orntNew[0] = -2;
7682: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
7683: orntNew[1] = 0;
7684: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7685: orntNew[2] = 0;
7686: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7687: orntNew[3] = -2;
7688: DMPlexSetCone(rdm, newp, coneNew);
7689: DMPlexSetConeOrientation(rdm, newp, orntNew);
7690: #if defined(PETSC_USE_DEBUG)
7691: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7692: for (p = 0; p < 4; ++p) {
7693: 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);
7694: }
7695: #endif
7696: /* E-H face */
7697: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
7698: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7699: orntNew[0] = -2;
7700: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
7701: orntNew[1] = -2;
7702: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
7703: orntNew[2] = 0;
7704: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7705: orntNew[3] = 0;
7706: DMPlexSetCone(rdm, newp, coneNew);
7707: DMPlexSetConeOrientation(rdm, newp, orntNew);
7708: #if defined(PETSC_USE_DEBUG)
7709: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7710: for (p = 0; p < 4; ++p) {
7711: 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);
7712: }
7713: #endif
7714: /* A-E face */
7715: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
7716: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
7717: orntNew[0] = 0;
7718: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7719: orntNew[1] = 0;
7720: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7721: orntNew[2] = -2;
7722: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
7723: orntNew[3] = -2;
7724: DMPlexSetCone(rdm, newp, coneNew);
7725: DMPlexSetConeOrientation(rdm, newp, orntNew);
7726: #if defined(PETSC_USE_DEBUG)
7727: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7728: for (p = 0; p < 4; ++p) {
7729: 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);
7730: }
7731: #endif
7732: /* D-F face */
7733: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
7734: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
7735: orntNew[0] = -2;
7736: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
7737: orntNew[1] = 0;
7738: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7739: orntNew[2] = 0;
7740: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7741: orntNew[3] = -2;
7742: DMPlexSetCone(rdm, newp, coneNew);
7743: DMPlexSetConeOrientation(rdm, newp, orntNew);
7744: #if defined(PETSC_USE_DEBUG)
7745: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7746: for (p = 0; p < 4; ++p) {
7747: 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);
7748: }
7749: #endif
7750: /* C-G face */
7751: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
7752: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7753: orntNew[0] = -2;
7754: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
7755: orntNew[1] = -2;
7756: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
7757: orntNew[2] = 0;
7758: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7759: orntNew[3] = 0;
7760: DMPlexSetCone(rdm, newp, coneNew);
7761: DMPlexSetConeOrientation(rdm, newp, orntNew);
7762: #if defined(PETSC_USE_DEBUG)
7763: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7764: for (p = 0; p < 4; ++p) {
7765: 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);
7766: }
7767: #endif
7768: /* B-H face */
7769: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
7770: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7771: orntNew[0] = 0;
7772: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7773: orntNew[1] = -2;
7774: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
7775: orntNew[2] = -2;
7776: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
7777: orntNew[3] = 0;
7778: DMPlexSetCone(rdm, newp, coneNew);
7779: DMPlexSetConeOrientation(rdm, newp, orntNew);
7780: #if defined(PETSC_USE_DEBUG)
7781: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7782: for (p = 0; p < 4; ++p) {
7783: 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);
7784: }
7785: #endif
7786: for (r = 0; r < 12; ++r) {
7787: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
7788: supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
7789: supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
7790: DMPlexSetSupport(rdm, newp, supportNew);
7791: #if defined(PETSC_USE_DEBUG)
7792: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7793: for (p = 0; p < 2; ++p) {
7794: 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);
7795: }
7796: #endif
7797: }
7798: }
7799: /* Hybrid split faces have 4 edges and same cells */
7800: for (f = fMax; f < fEnd; ++f) {
7801: const PetscInt *cone, *ornt, *support;
7802: PetscInt coneNew[4], orntNew[4];
7803: PetscInt supportNew[2], size, s, c;
7805: DMPlexGetCone(dm, f, &cone);
7806: DMPlexGetConeOrientation(dm, f, &ornt);
7807: DMPlexGetSupportSize(dm, f, &size);
7808: DMPlexGetSupport(dm, f, &support);
7809: for (r = 0; r < 2; ++r) {
7810: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
7812: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
7813: orntNew[0] = ornt[0];
7814: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
7815: orntNew[1] = ornt[1];
7816: coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
7817: orntNew[2+r] = 0;
7818: coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
7819: orntNew[3-r] = 0;
7820: DMPlexSetCone(rdm, newp, coneNew);
7821: DMPlexSetConeOrientation(rdm, newp, orntNew);
7822: #if defined(PETSC_USE_DEBUG)
7823: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
7824: for (p = 0; p < 2; ++p) {
7825: 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);
7826: }
7827: for (p = 2; p < 4; ++p) {
7828: 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);
7829: }
7830: #endif
7831: for (s = 0; s < size; ++s) {
7832: const PetscInt *coneCell, *orntCell, *fornt;
7833: PetscInt o, of;
7835: DMPlexGetCone(dm, support[s], &coneCell);
7836: DMPlexGetConeOrientation(dm, support[s], &orntCell);
7837: o = orntCell[0] < 0 ? -1 : 1;
7838: for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
7839: if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]);
7840: DMPlexGetConeOrientation(dm, coneCell[0], &fornt);
7841: of = fornt[c-2] < 0 ? -1 : 1;
7842: supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4;
7843: }
7844: DMPlexSetSupport(rdm, newp, supportNew);
7845: #if defined(PETSC_USE_DEBUG)
7846: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
7847: for (p = 0; p < size; ++p) {
7848: 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);
7849: }
7850: #endif
7851: }
7852: }
7853: /* Hybrid cell faces have 4 edges and 2 cells */
7854: for (c = cMax; c < cEnd; ++c) {
7855: PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
7856: const PetscInt *cone, *ornt;
7857: PetscInt coneNew[4], orntNew[4];
7858: PetscInt supportNew[2];
7860: DMPlexGetCone(dm, c, &cone);
7861: DMPlexGetConeOrientation(dm, c, &ornt);
7862: for (r = 0; r < 4; ++r) {
7863: #if 0
7864: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
7865: orntNew[0] = 0;
7866: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
7867: orntNew[1] = 0;
7868: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
7869: orntNew[2] = 0;
7870: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
7871: orntNew[3] = 0;
7872: #else
7873: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
7874: orntNew[0] = 0;
7875: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
7876: orntNew[1] = 0;
7877: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
7878: orntNew[2] = 0;
7879: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
7880: orntNew[3] = 0;
7881: #endif
7882: DMPlexSetCone(rdm, newp+r, coneNew);
7883: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
7884: #if defined(PETSC_USE_DEBUG)
7885: 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);
7886: for (p = 0; p < 2; ++p) {
7887: 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);
7888: }
7889: for (p = 2; p < 4; ++p) {
7890: 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);
7891: }
7892: #endif
7893: supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
7894: supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
7895: DMPlexSetSupport(rdm, newp+r, supportNew);
7896: #if defined(PETSC_USE_DEBUG)
7897: 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);
7898: for (p = 0; p < 2; ++p) {
7899: 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);
7900: }
7901: #endif
7902: }
7903: }
7904: /* Interior split edges have 2 vertices and the same faces as the parent */
7905: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
7906: for (e = eStart; e < eMax; ++e) {
7907: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
7909: for (r = 0; r < 2; ++r) {
7910: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
7911: const PetscInt *cone, *ornt, *support;
7912: PetscInt coneNew[2], coneSize, c, supportSize, s;
7914: DMPlexGetCone(dm, e, &cone);
7915: coneNew[0] = vStartNew + (cone[0] - vStart);
7916: coneNew[1] = vStartNew + (cone[1] - vStart);
7917: coneNew[(r+1)%2] = newv;
7918: DMPlexSetCone(rdm, newp, coneNew);
7919: #if defined(PETSC_USE_DEBUG)
7920: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7921: for (p = 0; p < 2; ++p) {
7922: 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);
7923: }
7924: #endif
7925: DMPlexGetSupportSize(dm, e, &supportSize);
7926: DMPlexGetSupport(dm, e, &support);
7927: for (s = 0; s < supportSize; ++s) {
7928: DMPlexGetConeSize(dm, support[s], &coneSize);
7929: DMPlexGetCone(dm, support[s], &cone);
7930: DMPlexGetConeOrientation(dm, support[s], &ornt);
7931: for (c = 0; c < coneSize; ++c) {
7932: if (cone[c] == e) break;
7933: }
7934: if (support[s] < fMax) {
7935: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
7936: } else {
7937: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
7938: }
7939: }
7940: DMPlexSetSupport(rdm, newp, supportRef);
7941: #if defined(PETSC_USE_DEBUG)
7942: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7943: for (p = 0; p < supportSize; ++p) {
7944: 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);
7945: }
7946: #endif
7947: }
7948: }
7949: /* Interior face edges have 2 vertices and 2+cells faces */
7950: for (f = fStart; f < fMax; ++f) {
7951: 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};
7952: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
7953: const PetscInt *cone, *coneCell, *orntCell, *support;
7954: PetscInt coneNew[2], coneSize, c, supportSize, s;
7956: DMPlexGetCone(dm, f, &cone);
7957: for (r = 0; r < 4; ++r) {
7958: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
7960: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
7961: coneNew[1] = newv;
7962: DMPlexSetCone(rdm, newp, coneNew);
7963: #if defined(PETSC_USE_DEBUG)
7964: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7965: for (p = 0; p < 2; ++p) {
7966: 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);
7967: }
7968: #endif
7969: DMPlexGetSupportSize(dm, f, &supportSize);
7970: DMPlexGetSupport(dm, f, &support);
7971: supportRef[0] = fStartNew + (f - fStart)*4 + r;
7972: supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
7973: for (s = 0; s < supportSize; ++s) {
7974: DMPlexGetConeSize(dm, support[s], &coneSize);
7975: DMPlexGetCone(dm, support[s], &coneCell);
7976: DMPlexGetConeOrientation(dm, support[s], &orntCell);
7977: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
7978: if (support[s] < cMax) {
7979: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
7980: } else {
7981: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
7982: }
7983: }
7984: DMPlexSetSupport(rdm, newp, supportRef);
7985: #if defined(PETSC_USE_DEBUG)
7986: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7987: for (p = 0; p < 2+supportSize; ++p) {
7988: 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);
7989: }
7990: #endif
7991: }
7992: }
7993: /* Interior cell edges have 2 vertices and 4 faces */
7994: for (c = cStart; c < cMax; ++c) {
7995: 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};
7996: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
7997: const PetscInt *cone;
7998: PetscInt coneNew[2], supportNew[4];
8000: DMPlexGetCone(dm, c, &cone);
8001: for (r = 0; r < 6; ++r) {
8002: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
8004: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
8005: coneNew[1] = newv;
8006: DMPlexSetCone(rdm, newp, coneNew);
8007: #if defined(PETSC_USE_DEBUG)
8008: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
8009: for (p = 0; p < 2; ++p) {
8010: 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);
8011: }
8012: #endif
8013: for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
8014: DMPlexSetSupport(rdm, newp, supportNew);
8015: #if defined(PETSC_USE_DEBUG)
8016: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
8017: for (p = 0; p < 4; ++p) {
8018: 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);
8019: }
8020: #endif
8021: }
8022: }
8023: /* Hybrid edges have two vertices and the same faces */
8024: for (e = eMax; e < eEnd; ++e) {
8025: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
8026: const PetscInt *cone, *support, *fcone;
8027: PetscInt coneNew[2], size, fsize, s;
8029: DMPlexGetCone(dm, e, &cone);
8030: DMPlexGetSupportSize(dm, e, &size);
8031: DMPlexGetSupport(dm, e, &support);
8032: coneNew[0] = vStartNew + (cone[0] - vStart);
8033: coneNew[1] = vStartNew + (cone[1] - vStart);
8034: DMPlexSetCone(rdm, newp, coneNew);
8035: #if defined(PETSC_USE_DEBUG)
8036: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8037: for (p = 0; p < 2; ++p) {
8038: 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);
8039: }
8040: #endif
8041: for (s = 0; s < size; ++s) {
8042: DMPlexGetConeSize(dm, support[s], &fsize);
8043: DMPlexGetCone(dm, support[s], &fcone);
8044: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
8045: if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]);
8046: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
8047: }
8048: DMPlexSetSupport(rdm, newp, supportRef);
8049: #if defined(PETSC_USE_DEBUG)
8050: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8051: for (p = 0; p < size; ++p) {
8052: 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);
8053: }
8054: #endif
8055: }
8056: /* Hybrid face edges have 2 vertices and 2+cells faces */
8057: for (f = fMax; f < fEnd; ++f) {
8058: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
8059: const PetscInt *cone, *support, *ccone, *cornt;
8060: PetscInt coneNew[2], size, csize, s;
8062: DMPlexGetCone(dm, f, &cone);
8063: DMPlexGetSupportSize(dm, f, &size);
8064: DMPlexGetSupport(dm, f, &support);
8065: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
8066: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
8067: DMPlexSetCone(rdm, newp, coneNew);
8068: #if defined(PETSC_USE_DEBUG)
8069: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8070: for (p = 0; p < 2; ++p) {
8071: 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);
8072: }
8073: #endif
8074: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
8075: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
8076: for (s = 0; s < size; ++s) {
8077: DMPlexGetConeSize(dm, support[s], &csize);
8078: DMPlexGetCone(dm, support[s], &ccone);
8079: DMPlexGetConeOrientation(dm, support[s], &cornt);
8080: for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
8081: 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]);
8082: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
8083: }
8084: DMPlexSetSupport(rdm, newp, supportRef);
8085: #if defined(PETSC_USE_DEBUG)
8086: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8087: for (p = 0; p < 2+size; ++p) {
8088: 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);
8089: }
8090: #endif
8091: }
8092: /* Hybrid cell edges have 2 vertices and 4 faces */
8093: for (c = cMax; c < cEnd; ++c) {
8094: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
8095: const PetscInt *cone, *support;
8096: PetscInt coneNew[2], size;
8098: DMPlexGetCone(dm, c, &cone);
8099: DMPlexGetSupportSize(dm, c, &size);
8100: DMPlexGetSupport(dm, c, &support);
8101: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
8102: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
8103: DMPlexSetCone(rdm, newp, coneNew);
8104: #if defined(PETSC_USE_DEBUG)
8105: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8106: for (p = 0; p < 2; ++p) {
8107: 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);
8108: }
8109: #endif
8110: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
8111: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
8112: supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
8113: supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
8114: DMPlexSetSupport(rdm, newp, supportRef);
8115: #if defined(PETSC_USE_DEBUG)
8116: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8117: for (p = 0; p < 4; ++p) {
8118: 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);
8119: }
8120: #endif
8121: }
8122: /* Interior vertices have identical supports */
8123: for (v = vStart; v < vEnd; ++v) {
8124: const PetscInt newp = vStartNew + (v - vStart);
8125: const PetscInt *support, *cone;
8126: PetscInt size, s;
8128: DMPlexGetSupportSize(dm, v, &size);
8129: DMPlexGetSupport(dm, v, &support);
8130: for (s = 0; s < size; ++s) {
8131: PetscInt r = 0;
8133: DMPlexGetCone(dm, support[s], &cone);
8134: if (cone[1] == v) r = 1;
8135: if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
8136: else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
8137: }
8138: DMPlexSetSupport(rdm, newp, supportRef);
8139: #if defined(PETSC_USE_DEBUG)
8140: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
8141: for (p = 0; p < size; ++p) {
8142: 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);
8143: }
8144: #endif
8145: }
8146: /* Interior edge vertices have 2 + faces supports */
8147: for (e = eStart; e < eMax; ++e) {
8148: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
8149: const PetscInt *cone, *support;
8150: PetscInt size, s;
8152: DMPlexGetSupportSize(dm, e, &size);
8153: DMPlexGetSupport(dm, e, &support);
8154: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
8155: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
8156: for (s = 0; s < size; ++s) {
8157: PetscInt r;
8159: DMPlexGetCone(dm, support[s], &cone);
8160: for (r = 0; r < 4; ++r) if (cone[r] == e) break;
8161: if (support[s] < fMax) {
8162: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
8163: } else {
8164: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
8165: }
8166: }
8167: DMPlexSetSupport(rdm, newp, supportRef);
8168: #if defined(PETSC_USE_DEBUG)
8169: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
8170: for (p = 0; p < 2+size; ++p) {
8171: 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);
8172: }
8173: #endif
8174: }
8175: /* Interior face vertices have 4 + cells supports */
8176: for (f = fStart; f < fMax; ++f) {
8177: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
8178: const PetscInt *cone, *support;
8179: PetscInt size, s;
8181: DMPlexGetSupportSize(dm, f, &size);
8182: DMPlexGetSupport(dm, f, &support);
8183: for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
8184: for (s = 0; s < size; ++s) {
8185: PetscInt r;
8187: DMPlexGetCone(dm, support[s], &cone);
8188: for (r = 0; r < 6; ++r) if (cone[r] == f) break;
8189: if (support[s] < cMax) {
8190: supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
8191: } else {
8192: supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
8193: }
8194: }
8195: DMPlexSetSupport(rdm, newp, supportRef);
8196: #if defined(PETSC_USE_DEBUG)
8197: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
8198: for (p = 0; p < 4+size; ++p) {
8199: 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);
8200: }
8201: #endif
8202: }
8203: /* Cell vertices have 6 supports */
8204: for (c = cStart; c < cMax; ++c) {
8205: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
8206: PetscInt supportNew[6];
8208: for (r = 0; r < 6; ++r) {
8209: supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
8210: }
8211: DMPlexSetSupport(rdm, newp, supportNew);
8212: }
8213: PetscFree(supportRef);
8214: break;
8215: default:
8216: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
8217: }
8218: return(0);
8219: }
8221: static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
8222: {
8223: PetscSection coordSection, coordSectionNew;
8224: Vec coordinates, coordinatesNew;
8225: PetscScalar *coords, *coordsNew;
8226: const PetscInt numVertices = depthSize ? depthSize[0] : 0;
8227: PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax;
8228: PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
8229: PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL;
8230: VecType vtype;
8231: PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE;
8232: const PetscReal *maxCell, *L;
8233: const DMBoundaryType *bd;
8234: PetscErrorCode ierr;
8237: DMGetDimension(dm, &dim);
8238: DMPlexGetDepth(dm, &depth);
8239: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
8240: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
8241: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
8242: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
8243: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);
8244: if (cMax < 0) cMax = cEnd;
8245: if (fMax < 0) fMax = fEnd;
8246: if (eMax < 0) eMax = eEnd;
8247: GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);
8248: GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);
8249: DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);
8250: /* Determine if we need to localize coordinates when generating them */
8251: if (isperiodic && !maxCell) {
8252: DMGetCoordinatesLocalized(dm, &localize);
8253: if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized");
8254: }
8255: if (isperiodic) {
8256: PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");
8257: PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);
8258: PetscOptionsEnd();
8259: if (localize) {
8260: DMLocalizeCoordinates(dm);
8261: }
8262: }
8263: DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);
8265: DMGetCoordinateSection(dm, &coordSection);
8266: PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);
8267: PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);
8268: PetscSectionSetNumFields(coordSectionNew, 1);
8269: PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);
8271: if (localize) {
8272: PetscInt p, r, newp, *pi;
8274: /* New coordinates will be already localized on the cell */
8275: PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);
8277: /* We need the parentId to properly localize coordinates */
8278: PetscMalloc1(cEndNew-cStartNew,&pi);
8279: switch (refiner) {
8280: case REFINER_NOOP:
8281: break;
8282: case REFINER_SIMPLEX_1D:
8283: for (p = cStart; p < cEnd; ++p) {
8284: for (r = 0; r < 2; ++r) {
8285: newp = (p - cStart)*2 + r;
8286: pi[newp] = p;
8287: }
8288: }
8289: break;
8290: case REFINER_SIMPLEX_2D:
8291: for (p = cStart; p < cEnd; ++p) {
8292: for (r = 0; r < 4; ++r) {
8293: newp = (p - cStart)*4 + r;
8294: pi[newp] = p;
8295: }
8296: }
8297: break;
8298: case REFINER_HEX_2D:
8299: for (p = cStart; p < cEnd; ++p) {
8300: for (r = 0; r < 4; ++r) {
8301: newp = (p - cStart)*4 + r;
8302: pi[newp] = p;
8303: }
8304: }
8305: break;
8306: case REFINER_SIMPLEX_TO_HEX_2D:
8307: for (p = cStart; p < cEnd; ++p) {
8308: for (r = 0; r < 3; ++r) {
8309: newp = (p - cStart)*3 + r;
8310: pi[newp] = p;
8311: }
8312: }
8313: break;
8314: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
8315: for (p = cStart; p < cMax; ++p) {
8316: for (r = 0; r < 3; ++r) {
8317: newp = (p - cStart)*3 + r;
8318: pi[newp] = p;
8319: }
8320: }
8321: for (p = cMax; p < cEnd; ++p) {
8322: for (r = 0; r < 4; ++r) {
8323: newp = (cMax - cStart)*3 + (p - cMax)*4 + r;
8324: pi[newp] = p;
8325: }
8326: }
8327: /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */
8328: cMax = cEnd;
8329: eMax = eEnd;
8330: break;
8331: case REFINER_HYBRID_SIMPLEX_2D:
8332: for (p = cStart; p < cMax; ++p) {
8333: for (r = 0; r < 4; ++r) {
8334: newp = (p - cStart)*4 + r;
8335: pi[newp] = p;
8336: }
8337: }
8338: for (p = cMax; p < cEnd; ++p) {
8339: for (r = 0; r < 2; ++r) {
8340: newp = (cMax - cStart)*4 + (p - cMax)*2 + r;
8341: pi[newp] = p;
8342: }
8343: }
8344: break;
8345: case REFINER_HYBRID_HEX_2D:
8346: for (p = cStart; p < cMax; ++p) {
8347: for (r = 0; r < 4; ++r) {
8348: newp = (p - cStart)*4 + r;
8349: pi[newp] = p;
8350: }
8351: }
8352: for (p = cMax; p < cEnd; ++p) {
8353: for (r = 0; r < 2; ++r) {
8354: newp = (cMax - cStart)*4 + (p - cMax)*2 + r;
8355: pi[newp] = p;
8356: }
8357: }
8358: break;
8359: case REFINER_SIMPLEX_3D:
8360: for (p = cStart; p < cEnd; ++p) {
8361: for (r = 0; r < 8; ++r) {
8362: newp = (p - cStart)*8 + r;
8363: pi[newp] = p;
8364: }
8365: }
8366: break;
8367: case REFINER_HYBRID_SIMPLEX_3D:
8368: for (p = cStart; p < cMax; ++p) {
8369: for (r = 0; r < 8; ++r) {
8370: newp = (p - cStart)*8 + r;
8371: pi[newp] = p;
8372: }
8373: }
8374: for (p = cMax; p < cEnd; ++p) {
8375: for (r = 0; r < 4; ++r) {
8376: newp = (cMax - cStart)*8 + (p - cMax)*4 + r;
8377: pi[newp] = p;
8378: }
8379: }
8380: break;
8381: case REFINER_SIMPLEX_TO_HEX_3D:
8382: for (p = cStart; p < cEnd; ++p) {
8383: for (r = 0; r < 4; ++r) {
8384: newp = (p - cStart)*4 + r;
8385: pi[newp] = p;
8386: }
8387: }
8388: break;
8389: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
8390: for (p = cStart; p < cMax; ++p) {
8391: for (r = 0; r < 4; ++r) {
8392: newp = (p - cStart)*4 + r;
8393: pi[newp] = p;
8394: }
8395: }
8396: for (p = cMax; p < cEnd; ++p) {
8397: for (r = 0; r < 3; ++r) {
8398: newp = (cMax - cStart)*4 + (p - cMax)*3 + r;
8399: pi[newp] = p;
8400: }
8401: }
8402: break;
8403: case REFINER_HEX_3D:
8404: for (p = cStart; p < cEnd; ++p) {
8405: for (r = 0; r < 8; ++r) {
8406: newp = (p - cStart)*8 + r;
8407: pi[newp] = p;
8408: }
8409: }
8410: break;
8411: case REFINER_HYBRID_HEX_3D:
8412: for (p = cStart; p < cMax; ++p) {
8413: for (r = 0; r < 8; ++r) {
8414: newp = (p - cStart)*8 + r;
8415: pi[newp] = p;
8416: }
8417: }
8418: for (p = cMax; p < cEnd; ++p) {
8419: for (r = 0; r < 4; ++r) {
8420: newp = (cMax - cStart)*8 + (p - cMax)*4 + r;
8421: pi[newp] = p;
8422: }
8423: }
8424: break;
8425: default:
8426: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
8427: }
8428: parentId = pi;
8429: } else {
8430: /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */
8431: if (REFINER_HYBRID_SIMPLEX_TO_HEX_2D == refiner) { cMax = cEnd; eMax = eEnd; }
8432: PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);
8433: }
8435: /* All vertices have the spaceDim coordinates */
8436: if (localize) {
8437: PetscInt c;
8439: for (c = cStartNew; c < cEndNew; ++c) {
8440: PetscInt *cone = NULL;
8441: PetscInt closureSize, coneSize = 0, p, pdof;
8443: PetscSectionGetDof(coordSection, parentId[c], &pdof);
8444: if (pdof) { /* localize on all cells that are refinement of a localized parent cell */
8445: DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8446: for (p = 0; p < closureSize*2; p += 2) {
8447: const PetscInt point = cone[p];
8448: if ((point >= vStartNew) && (point < vEndNew)) coneSize++;
8449: }
8450: DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8451: PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);
8452: PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);
8453: }
8454: }
8455: }
8456: for (v = vStartNew; v < vStartNew+numVertices; ++v) {
8457: PetscSectionSetDof(coordSectionNew, v, spaceDim);
8458: PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);
8459: }
8460: PetscSectionSetUp(coordSectionNew);
8461: DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);
8462: DMGetCoordinatesLocal(dm, &coordinates);
8463: PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);
8464: VecCreate(PETSC_COMM_SELF, &coordinatesNew);
8465: PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");
8466: VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);
8467: VecGetBlockSize(coordinates, &bs);
8468: VecSetBlockSize(coordinatesNew, bs);
8469: VecGetType(coordinates, &vtype);
8470: VecSetType(coordinatesNew, vtype);
8471: VecGetArray(coordinates, &coords);
8472: VecGetArray(coordinatesNew, &coordsNew);
8474: switch (refiner) {
8475: case REFINER_NOOP: break;
8476: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
8477: case REFINER_SIMPLEX_TO_HEX_3D:
8478: case REFINER_HEX_3D:
8479: case REFINER_HYBRID_HEX_3D:
8480: /* Face vertices have the average of corner coordinates */
8481: for (f = fStart; f < fMax; ++f) {
8482: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
8483: PetscInt *cone = NULL;
8484: PetscInt closureSize, coneSize = 0, off[8], offnew, p, d;
8486: DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);
8487: for (p = 0; p < closureSize*2; p += 2) {
8488: const PetscInt point = cone[p];
8489: if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
8490: }
8491: if (localize) {
8492: const PetscInt *support = NULL;
8493: PetscInt *rStar = NULL;
8494: PetscInt supportSize, rStarSize, coff, s, ccoff[8];
8495: PetscBool cellfound = PETSC_FALSE;
8497: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8498: DMPlexGetSupportSize(dm,f,&supportSize);
8499: DMPlexGetSupport(dm,f,&support);
8500: /* Compute average of coordinates for each cell sharing the face */
8501: for (s = 0; s < supportSize; ++s) {
8502: PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 };
8503: PetscInt *cellCone = NULL;
8504: PetscInt cellClosureSize, cellConeSize = 0, cdof;
8505: const PetscInt cell = support[s];
8506: PetscBool copyoff = PETSC_FALSE;
8508: DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8509: for (p = 0; p < cellClosureSize*2; p += 2) {
8510: const PetscInt point = cellCone[p];
8511: if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point;
8512: }
8513: PetscSectionGetDof(coordSection, cell, &cdof);
8514: if (!cdof) { /* the parent cell does not have localized coordinates */
8515: cellfound = PETSC_TRUE;
8516: for (v = 0; v < coneSize; ++v) {
8517: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
8518: for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d];
8519: }
8520: for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
8521: } else {
8522: PetscSectionGetOffset(coordSection, cell, &coff);
8523: for (p = 0; p < coneSize; ++p) {
8524: const PetscInt tv = cone[p];
8525: PetscInt cv, voff;
8526: PetscBool locv = PETSC_TRUE;
8528: for (cv = 0; cv < cellConeSize; ++cv) {
8529: if (cellCone[cv] == tv) {
8530: ccoff[p] = spaceDim*cv + coff;
8531: break;
8532: }
8533: }
8534: if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D",tv);
8536: PetscSectionGetOffset(coordSection, cone[p], &voff);
8537: for (d = 0; d < spaceDim; ++d) {
8538: coordsNewAux[d] += coords[ccoff[p]+d];
8539: if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE;
8540: }
8541: if (locv && !cellfound) {
8542: cellfound = PETSC_TRUE;
8543: copyoff = PETSC_TRUE;
8544: }
8545: }
8546: for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
8548: /* Found a valid face for the "vertex" part of the Section (physical space)
8549: i.e., a face that has at least one corner in the physical space */
8550: if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p];
8551: }
8553: /* Localize new coordinates on each refined cell */
8554: for (v = 0; v < rStarSize*2; v += 2) {
8555: if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) {
8556: PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff;
8557: const PetscInt rcell = rStar[v];
8559: PetscSectionGetDof(coordSectionNew, rcell, &rcdof);
8560: if (!rcdof) continue;
8561: PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);
8562: DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8563: for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
8564: if (rcone[p] == newv) {
8565: for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d];
8566: break;
8567: }
8568: if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
8569: }
8570: DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8571: if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8572: }
8573: }
8574: DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8575: }
8576: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8577: if (!cellfound) {
8578: /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */
8579: needcoords = PETSC_TRUE;
8580: coneSize = 0;
8581: }
8582: } else {
8583: for (v = 0; v < coneSize; ++v) {
8584: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
8585: }
8586: }
8587: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8588: if (coneSize) {
8589: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
8590: for (v = 0; v < coneSize; ++v) {DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);}
8591: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
8592: } else {
8593: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
8594: }
8595: DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);
8596: }
8597: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
8598: case REFINER_SIMPLEX_TO_HEX_2D:
8599: case REFINER_HEX_2D:
8600: case REFINER_HYBRID_HEX_2D:
8601: case REFINER_SIMPLEX_1D:
8602: /* Cell vertices have the average of corner coordinates */
8603: for (c = cStart; c < cMax; ++c) {
8604: const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
8605: PetscInt *cone = NULL;
8606: PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0;
8608: DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);
8609: for (p = 0; p < closureSize*2; p += 2) {
8610: const PetscInt point = cone[p];
8611: if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
8612: }
8613: if (localize) {
8614: PetscSectionGetDof(coordSection, c, &cdof);
8615: }
8616: if (cdof) {
8617: PetscInt coff;
8619: PetscSectionGetOffset(coordSection, c, &coff);
8620: for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff;
8621: } else {
8622: for (v = 0; v < coneSize; ++v) {
8623: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
8624: }
8625: }
8626: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8627: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
8628: for (v = 0; v < coneSize; ++v) {DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);}
8629: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
8630: DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);
8632: /* Localize new coordinates on each refined cell */
8633: if (cdof) {
8634: PetscInt *rStar = NULL, rStarSize;
8636: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8637: for (v = 0; v < rStarSize*2; v += 2) {
8638: if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) {
8639: PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof;
8641: rc = rStar[v];
8642: PetscSectionGetDof(coordSectionNew, rc, &rcdof);
8643: if (!rcdof) continue;
8644: PetscSectionGetOffset(coordSectionNew, rc, &coff);
8645: DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);
8646: for (p = 0, lid = 0; p < closureSize*2; p += 2) {
8647: if (cone[p] == newv) {
8648: for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d];
8649: break;
8650: }
8651: if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++;
8652: }
8653: if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8654: DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);
8655: }
8656: }
8657: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8658: }
8659: }
8660: case REFINER_SIMPLEX_2D:
8661: case REFINER_HYBRID_SIMPLEX_2D:
8662: case REFINER_SIMPLEX_3D:
8663: case REFINER_HYBRID_SIMPLEX_3D:
8664: /* Edge vertices have the average of endpoint coordinates */
8665: for (e = eStart; e < eMax; ++e) {
8666: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
8667: const PetscInt *cone;
8668: PetscInt coneSize, offA, offB, offnew, d;
8670: DMPlexGetConeSize(dm, e, &coneSize);
8671: if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize);
8672: DMPlexGetCone(dm, e, &cone);
8673: if (localize) {
8674: PetscInt coff, toffA = -1, toffB = -1, voffA, voffB;
8675: PetscInt *eStar = NULL, eStarSize;
8676: PetscInt *rStar = NULL, rStarSize;
8677: PetscBool cellfound = PETSC_FALSE;
8679: offA = offB = -1;
8680: PetscSectionGetOffset(coordSection, cone[0], &voffA);
8681: PetscSectionGetOffset(coordSection, cone[1], &voffB);
8682: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);
8683: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8684: for (v = 0; v < eStarSize*2; v += 2) {
8685: if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) {
8686: PetscScalar coordsNewAux[3] = {0., 0., 0.};
8687: PetscInt *cellCone = NULL;
8688: PetscInt cellClosureSize, s, cv, cdof;
8689: PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE;
8690: const PetscInt cell = eStar[v];
8692: PetscSectionGetDof(coordSection, cell, &cdof);
8693: if (!cdof) {
8694: /* Found a valid edge for the "vertex" part of the Section */
8695: offA = voffA;
8696: offB = voffB;
8697: cellfound = PETSC_TRUE;
8698: } else {
8699: PetscSectionGetOffset(coordSection, cell, &coff);
8700: DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8701: for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) {
8702: const PetscInt point = cellCone[s];
8703: if ((point >= vStart) && (point < vEnd)) {
8704: if (point == cone[0]) toffA = spaceDim*cv + coff;
8705: else if (point == cone[1]) toffB = spaceDim*cv + coff;
8706: cv++;
8707: }
8708: }
8709: DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8710: for (d = 0; d < spaceDim; ++d) {
8711: coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]);
8712: if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE;
8713: if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE;
8714: }
8715: /* Found a valid edge for the "vertex" part of the Section */
8716: if (!cellfound && (locvA || locvB)) {
8717: cellfound = PETSC_TRUE;
8718: offA = toffA;
8719: offB = toffB;
8720: }
8721: }
8723: /* Localize new coordinates on each refined cell */
8724: for (s = 0; s < rStarSize*2; s += 2) {
8725: if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) {
8726: PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof;
8727: const PetscInt rcell = rStar[s];
8729: PetscSectionGetDof(coordSectionNew, rcell, &rcdof);
8730: if (!rcdof) continue;
8731: PetscSectionGetOffset(coordSectionNew, rcell, &coff);
8732: DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8733: for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
8734: if (rcone[p] == newv) {
8735: for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d];
8736: break;
8737: }
8738: if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
8739: }
8740: DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8741: if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8742: }
8743: }
8744: }
8745: }
8746: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);
8747: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8748: if (!cellfound) {
8749: /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */
8750: needcoords = PETSC_TRUE;
8751: }
8752: } else {
8753: PetscSectionGetOffset(coordSection, cone[0], &offA);
8754: PetscSectionGetOffset(coordSection, cone[1], &offB);
8755: }
8756: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8757: if (offA != -1 && offB != -1) {
8758: DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);
8759: for (d = 0; d < spaceDim; ++d) {
8760: coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
8761: }
8762: } else {
8763: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
8764: }
8765: }
8766: /* Old vertices have the same coordinates */
8767: for (v = vStart; v < vEnd; ++v) {
8768: const PetscInt newv = vStartNew + (v - vStart);
8769: PetscInt off, offnew, d;
8771: PetscSectionGetOffset(coordSection, v, &off);
8772: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8773: for (d = 0; d < spaceDim; ++d) {
8774: coordsNew[offnew+d] = coords[off+d];
8775: }
8777: /* Localize new coordinates on each refined cell */
8778: if (localize) {
8779: PetscInt p;
8780: PetscInt *rStar = NULL, rStarSize;
8782: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8783: for (p = 0; p < rStarSize*2; p += 2) {
8784: if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) {
8785: PetscScalar ocoords[3] = {0,0,0}; /* dummy values for compiler warnings about uninitialized values */
8786: PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof;
8788: c = rStar[p];
8789: oc = parentId[c-cStartNew];
8790: PetscSectionGetDof(coordSectionNew, c, &cdof);
8791: if (!cdof) continue;
8792: PetscSectionGetDof(coordSection, oc, &cdof);
8793: if (!cdof) continue;
8794: PetscSectionGetOffset(coordSection, oc, &coff);
8795: DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);
8796: for (s = 0, lid = 0; s < closureSize*2; s += 2) {
8797: if (cone[s] == v) {
8798: for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d];
8799: break;
8800: }
8801: if (cone[s] >= vStart && cone[s] < vEnd) lid++;
8802: }
8803: if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D",v);
8804: DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);
8806: PetscSectionGetOffset(coordSectionNew, c, &coff);
8807: DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8808: for (s = 0, lid = 0; s < closureSize*2; s += 2) {
8809: if (cone[s] == newv) {
8810: for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d];
8811: break;
8812: }
8813: if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++;
8814: }
8815: if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8816: DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8817: }
8818: }
8819: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8820: }
8821: }
8822: break;
8823: default:
8824: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
8825: }
8826: VecRestoreArray(coordinates, &coords);
8827: VecRestoreArray(coordinatesNew, &coordsNew);
8828: DMSetCoordinatesLocal(rdm, coordinatesNew);
8830: /* Final reduction (if needed) if we are localizing */
8831: if (localize) {
8832: PetscBool gred;
8834: MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));
8835: if (gred) {
8836: DM cdm;
8837: Vec aux;
8838: PetscSF sf;
8839: const PetscScalar *lArray;
8840: PetscScalar *gArray;
8841: #if defined(PETSC_USE_COMPLEX)
8842: PetscInt i, ln, gn;
8843: PetscReal *lrArray;
8844: PetscReal *grArray;
8845: #endif
8847: DMGetCoordinateDM(rdm, &cdm);
8848: DMCreateGlobalVector(cdm, &aux);
8849: DMGetSectionSF(cdm, &sf);
8850: VecGetArrayRead(coordinatesNew, &lArray);
8851: VecSet(aux, PETSC_MIN_REAL);
8852: VecGetArray(aux, &gArray);
8853: #if defined(PETSC_USE_COMPLEX)
8854: VecGetLocalSize(aux, &gn);
8855: VecGetLocalSize(coordinatesNew, &ln);
8856: PetscMalloc2(ln,&lrArray,gn,&grArray);
8857: for (i=0;i<ln;i++) lrArray[i] = PetscRealPart(lArray[i]);
8858: for (i=0;i<gn;i++) grArray[i] = PetscRealPart(gArray[i]);
8859: PetscSFReduceBegin(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);
8860: PetscSFReduceEnd(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);
8861: for (i=0;i<gn;i++) gArray[i] = grArray[i];
8862: PetscFree2(lrArray,grArray);
8863: #else
8864: PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);
8865: PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);
8866: #endif
8867: VecRestoreArrayRead(coordinatesNew, &lArray);
8868: VecRestoreArray(aux, &gArray);
8869: DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);
8870: DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);
8871: VecDestroy(&aux);
8872: }
8873: }
8874: VecDestroy(&coordinatesNew);
8875: PetscSectionDestroy(&coordSectionNew);
8876: PetscFree(parentId);
8877: return(0);
8878: }
8880: /*@
8881: DMPlexCreateProcessSF - Create an SF which just has process connectivity
8883: Collective on dm
8885: Input Parameters:
8886: + dm - The DM
8887: - sfPoint - The PetscSF which encodes point connectivity
8889: Output Parameters:
8890: + processRanks - A list of process neighbors, or NULL
8891: - sfProcess - An SF encoding the process connectivity, or NULL
8893: Level: developer
8895: .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
8896: @*/
8897: PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
8898: {
8899: PetscInt numRoots, numLeaves, l;
8900: const PetscInt *localPoints;
8901: const PetscSFNode *remotePoints;
8902: PetscInt *localPointsNew;
8903: PetscSFNode *remotePointsNew;
8904: PetscInt *ranks, *ranksNew;
8905: PetscMPIInt size;
8906: PetscErrorCode ierr;
8913: MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);
8914: PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);
8915: PetscMalloc1(numLeaves, &ranks);
8916: for (l = 0; l < numLeaves; ++l) {
8917: ranks[l] = remotePoints[l].rank;
8918: }
8919: PetscSortRemoveDupsInt(&numLeaves, ranks);
8920: PetscMalloc1(numLeaves, &ranksNew);
8921: PetscMalloc1(numLeaves, &localPointsNew);
8922: PetscMalloc1(numLeaves, &remotePointsNew);
8923: for (l = 0; l < numLeaves; ++l) {
8924: ranksNew[l] = ranks[l];
8925: localPointsNew[l] = l;
8926: remotePointsNew[l].index = 0;
8927: remotePointsNew[l].rank = ranksNew[l];
8928: }
8929: PetscFree(ranks);
8930: if (processRanks) {ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);}
8931: else {PetscFree(ranksNew);}
8932: if (sfProcess) {
8933: PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);
8934: PetscObjectSetName((PetscObject) *sfProcess, "Process SF");
8935: PetscSFSetFromOptions(*sfProcess);
8936: PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);
8937: }
8938: return(0);
8939: }
8941: static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
8942: {
8943: PetscSF sf, sfNew, sfProcess;
8944: IS processRanks;
8945: MPI_Datatype depthType;
8946: PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m;
8947: const PetscInt *localPoints, *neighbors;
8948: const PetscSFNode *remotePoints;
8949: PetscInt *localPointsNew;
8950: PetscSFNode *remotePointsNew;
8951: PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
8952: PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
8953: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
8954: PetscErrorCode ierr;
8957: DMPlexGetChart(rdm, &pStartNew, &pEndNew);
8958: DMPlexGetDepth(dm, &ldepth);
8959: MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));
8960: if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %D != %D", ldepth, depth);
8961: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
8962: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
8963: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
8964: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
8965: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
8966: cMax = cMax < 0 ? cEnd : cMax;
8967: fMax = fMax < 0 ? fEnd : fMax;
8968: eMax = eMax < 0 ? eEnd : eMax;
8969: if (refiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
8970: DMGetPointSF(dm, &sf);
8971: DMGetPointSF(rdm, &sfNew);
8972: /* Calculate size of new SF */
8973: PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);
8974: if (numRoots < 0) return(0);
8975: for (l = 0; l < numLeaves; ++l) {
8976: const PetscInt p = localPoints[l];
8978: switch (refiner) {
8979: case REFINER_SIMPLEX_1D:
8980: if ((p >= vStart) && (p < vEnd)) {
8981: /* Interior vertices stay the same */
8982: ++numLeavesNew;
8983: } else if ((p >= cStart && p < cMax)) {
8984: /* Interior cells add new cells and interior vertices */
8985: numLeavesNew += 2 + 1;
8986: }
8987: break;
8988: case REFINER_SIMPLEX_2D:
8989: case REFINER_HYBRID_SIMPLEX_2D:
8990: if ((p >= vStart) && (p < vEnd)) {
8991: /* Interior vertices stay the same */
8992: ++numLeavesNew;
8993: } else if ((p >= fStart) && (p < fMax)) {
8994: /* Interior faces add new faces and vertex */
8995: numLeavesNew += 2 + 1;
8996: } else if ((p >= fMax) && (p < fEnd)) {
8997: /* Hybrid faces stay the same */
8998: ++numLeavesNew;
8999: } else if ((p >= cStart) && (p < cMax)) {
9000: /* Interior cells add new cells and interior faces */
9001: numLeavesNew += 4 + 3;
9002: } else if ((p >= cMax) && (p < cEnd)) {
9003: /* Hybrid cells add new cells and hybrid face */
9004: numLeavesNew += 2 + 1;
9005: }
9006: break;
9007: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9008: case REFINER_SIMPLEX_TO_HEX_2D:
9009: if ((p >= vStart) && (p < vEnd)) {
9010: /* Interior vertices stay the same */
9011: ++numLeavesNew;
9012: } else if ((p >= fStart) && (p < fEnd)) {
9013: /* Interior faces add new faces and vertex */
9014: numLeavesNew += 2 + 1;
9015: } else if ((p >= cStart) && (p < cMax)) {
9016: /* Interior cells add new cells, interior faces, and vertex */
9017: numLeavesNew += 3 + 3 + 1;
9018: } else if ((p >= cMax) && (p < cEnd)) {
9019: /* Hybrid cells add new cells, interior faces, and vertex */
9020: numLeavesNew += 4 + 4 + 1;
9021: }
9022: break;
9023: case REFINER_HEX_2D:
9024: case REFINER_HYBRID_HEX_2D:
9025: if ((p >= vStart) && (p < vEnd)) {
9026: /* Interior vertices stay the same */
9027: ++numLeavesNew;
9028: } else if ((p >= fStart) && (p < fMax)) {
9029: /* Interior faces add new faces and vertex */
9030: numLeavesNew += 2 + 1;
9031: } else if ((p >= fMax) && (p < fEnd)) {
9032: /* Hybrid faces stay the same */
9033: ++numLeavesNew;
9034: } else if ((p >= cStart) && (p < cMax)) {
9035: /* Interior cells add new cells, interior faces, and vertex */
9036: numLeavesNew += 4 + 4 + 1;
9037: } else if ((p >= cMax) && (p < cEnd)) {
9038: /* Hybrid cells add new cells and hybrid face */
9039: numLeavesNew += 2 + 1;
9040: }
9041: break;
9042: case REFINER_SIMPLEX_3D:
9043: case REFINER_HYBRID_SIMPLEX_3D:
9044: if ((p >= vStart) && (p < vEnd)) {
9045: /* Interior vertices stay the same */
9046: ++numLeavesNew;
9047: } else if ((p >= eStart) && (p < eMax)) {
9048: /* Interior edges add new edges and vertex */
9049: numLeavesNew += 2 + 1;
9050: } else if ((p >= eMax) && (p < eEnd)) {
9051: /* Hybrid edges stay the same */
9052: ++numLeavesNew;
9053: } else if ((p >= fStart) && (p < fMax)) {
9054: /* Interior faces add new faces and edges */
9055: numLeavesNew += 4 + 3;
9056: } else if ((p >= fMax) && (p < fEnd)) {
9057: /* Hybrid faces add new faces and edges */
9058: numLeavesNew += 2 + 1;
9059: } else if ((p >= cStart) && (p < cMax)) {
9060: /* Interior cells add new cells, faces, and edges */
9061: numLeavesNew += 8 + 8 + 1;
9062: } else if ((p >= cMax) && (p < cEnd)) {
9063: /* Hybrid cells add new cells and faces */
9064: numLeavesNew += 4 + 3;
9065: }
9066: break;
9067: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9068: case REFINER_SIMPLEX_TO_HEX_3D:
9069: if ((p >= vStart) && (p < vEnd)) {
9070: /* Interior vertices stay the same */
9071: ++numLeavesNew;
9072: } else if ((p >= eStart) && (p < eMax)) {
9073: /* Interior edges add new edges and vertex */
9074: numLeavesNew += 2 + 1;
9075: } else if ((p >= eMax) && (p < eEnd)) {
9076: /* Hybrid edges stay the same */
9077: ++numLeavesNew;
9078: } else if ((p >= fStart) && (p < fMax)) {
9079: /* Interior faces add new faces, edges and a vertex */
9080: numLeavesNew += 3 + 3 + 1;
9081: } else if ((p >= fMax) && (p < fEnd)) {
9082: /* Hybrid faces add new faces and an edge */
9083: numLeavesNew += 2 + 1;
9084: } else if ((p >= cStart) && (p < cMax)) {
9085: /* Interior cells add new cells, faces, edges and a vertex */
9086: numLeavesNew += 4 + 6 + 4 + 1;
9087: } else if ((p >= cMax) && (p < cEnd)) {
9088: /* Hybrid cells add new cells, faces and an edge */
9089: numLeavesNew += 3 + 3 + 1;
9090: }
9091: break;
9092: case REFINER_HEX_3D:
9093: case REFINER_HYBRID_HEX_3D:
9094: if ((p >= vStart) && (p < vEnd)) {
9095: /* Old vertices stay the same */
9096: ++numLeavesNew;
9097: } else if ((p >= eStart) && (p < eMax)) {
9098: /* Interior edges add new edges, and vertex */
9099: numLeavesNew += 2 + 1;
9100: } else if ((p >= eMax) && (p < eEnd)) {
9101: /* Hybrid edges stay the same */
9102: ++numLeavesNew;
9103: } else if ((p >= fStart) && (p < fMax)) {
9104: /* Interior faces add new faces, edges, and vertex */
9105: numLeavesNew += 4 + 4 + 1;
9106: } else if ((p >= fMax) && (p < fEnd)) {
9107: /* Hybrid faces add new faces and edges */
9108: numLeavesNew += 2 + 1;
9109: } else if ((p >= cStart) && (p < cMax)) {
9110: /* Interior cells add new cells, faces, edges, and vertex */
9111: numLeavesNew += 8 + 12 + 6 + 1;
9112: } else if ((p >= cStart) && (p < cEnd)) {
9113: /* Hybrid cells add new cells, faces, and edges */
9114: numLeavesNew += 4 + 4 + 1;
9115: }
9116: break;
9117: default:
9118: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
9119: }
9120: }
9121: /* Communicate depthSizes for each remote rank */
9122: DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);
9123: ISGetLocalSize(processRanks, &numNeighbors);
9124: PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);
9125: PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);
9126: MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);
9127: MPI_Type_commit(&depthType);
9128: PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);
9129: PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);
9130: for (n = 0; n < numNeighbors; ++n) {
9131: GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);
9132: }
9133: depthSizeOld[depth] = cMax;
9134: depthSizeOld[0] = vMax;
9135: depthSizeOld[depth-1] = fMax;
9136: depthSizeOld[1] = eMax;
9138: PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);
9139: PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);
9141: depthSizeOld[depth] = cEnd - cStart;
9142: depthSizeOld[0] = vEnd - vStart;
9143: depthSizeOld[depth-1] = fEnd - fStart;
9144: depthSizeOld[1] = eEnd - eStart;
9146: PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);
9147: PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);
9148: for (n = 0; n < numNeighbors; ++n) {
9149: GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);
9150: rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth];
9151: 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];
9152: rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1];
9153: }
9154: MPI_Type_free(&depthType);
9155: PetscSFDestroy(&sfProcess);
9156: /* Calculate new point SF */
9157: PetscMalloc1(numLeavesNew, &localPointsNew);
9158: PetscMalloc1(numLeavesNew, &remotePointsNew);
9159: ISGetIndices(processRanks, &neighbors);
9160: for (l = 0, m = 0; l < numLeaves; ++l) {
9161: PetscInt p = localPoints[l];
9162: PetscInt rp = remotePoints[l].index, n;
9163: PetscMPIInt rrank = remotePoints[l].rank;
9165: PetscFindInt(rrank, numNeighbors, neighbors, &n);
9166: if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rrank);
9167: switch (refiner) {
9168: case REFINER_SIMPLEX_1D:
9169: if ((p >= vStart) && (p < vEnd)) {
9170: /* Old vertices stay the same */
9171: localPointsNew[m] = vStartNew + (p - vStart);
9172: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9173: remotePointsNew[m].rank = rrank;
9174: ++m;
9175: } else if ((p >= cStart) && (p < cMax)) {
9176: /* Old interior cells add new cells and vertex */
9177: for (r = 0; r < 2; ++r, ++m) {
9178: localPointsNew[m] = cStartNew + (p - cStart)*2 + r;
9179: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r;
9180: remotePointsNew[m].rank = rrank;
9181: }
9182: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart);
9183: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]);
9184: remotePointsNew[m].rank = rrank;
9185: ++m;
9186: }
9187: break;
9188: case REFINER_SIMPLEX_2D:
9189: case REFINER_HYBRID_SIMPLEX_2D:
9190: if ((p >= vStart) && (p < vEnd)) {
9191: /* Old vertices stay the same */
9192: localPointsNew[m] = vStartNew + (p - vStart);
9193: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9194: remotePointsNew[m].rank = rrank;
9195: ++m;
9196: } else if ((p >= fStart) && (p < fMax)) {
9197: /* Old interior faces add new faces and vertex */
9198: for (r = 0; r < 2; ++r, ++m) {
9199: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
9200: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
9201: remotePointsNew[m].rank = rrank;
9202: }
9203: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
9204: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
9205: remotePointsNew[m].rank = rrank;
9206: ++m;
9207: } else if ((p >= fMax) && (p < fEnd)) {
9208: /* Old hybrid faces stay the same */
9209: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax);
9210: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
9211: remotePointsNew[m].rank = rrank;
9212: ++m;
9213: } else if ((p >= cStart) && (p < cMax)) {
9214: /* Old interior cells add new cells and interior faces */
9215: for (r = 0; r < 4; ++r, ++m) {
9216: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9217: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9218: remotePointsNew[m].rank = rrank;
9219: }
9220: for (r = 0; r < 3; ++r, ++m) {
9221: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r;
9222: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
9223: remotePointsNew[m].rank = rrank;
9224: }
9225: } else if ((p >= cMax) && (p < cEnd)) {
9226: /* Old hybrid cells add new cells and hybrid face */
9227: for (r = 0; r < 2; ++r, ++m) {
9228: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9229: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9230: remotePointsNew[m].rank = rrank;
9231: }
9232: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
9233: 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]);
9234: remotePointsNew[m].rank = rrank;
9235: ++m;
9236: }
9237: break;
9238: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9239: case REFINER_SIMPLEX_TO_HEX_2D:
9240: if ((p >= vStart) && (p < vEnd)) {
9241: /* Old vertices stay the same */
9242: localPointsNew[m] = vStartNew + (p - vStart);
9243: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9244: remotePointsNew[m].rank = rrank;
9245: ++m;
9246: } else if ((p >= fStart) && (p < fEnd)) {
9247: /* Old interior faces add new faces and vertex */
9248: for (r = 0; r < 2; ++r, ++m) {
9249: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
9250: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
9251: remotePointsNew[m].rank = rrank;
9252: }
9253: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
9254: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
9255: remotePointsNew[m].rank = rrank;
9256: ++m;
9257: } else if ((p >= cStart) && (p < cMax)) {
9258: /* Old interior cells add new cells, interior faces, and a vertex */
9259: for (r = 0; r < 3; ++r, ++m) {
9260: localPointsNew[m] = cStartNew + (p - cStart)*3 + r;
9261: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r;
9262: remotePointsNew[m].rank = rrank;
9263: }
9264: for (r = 0; r < 3; ++r, ++m) {
9265: localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9266: remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
9267: remotePointsNew[m].rank = rrank;
9268: }
9269: localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9270: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
9271: remotePointsNew[m].rank = rrank;
9272: ++m;
9273: } else if ((p >= cMax) && (p < cEnd)) {
9274: /* Old interior hybrid cells add new cells, interior faces, and a vertex */
9275: for (r = 0; r < 4; ++r, ++m) {
9276: localPointsNew[m] = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r;
9277: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
9278: remotePointsNew[m].rank = rrank;
9279: }
9280: for (r = 0; r < 4; ++r, ++m) {
9281: localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r;
9282: 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;
9283: remotePointsNew[m].rank = rrank;
9284: }
9285: localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9286: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
9287: remotePointsNew[m].rank = rrank;
9288: ++m;
9289: }
9290: break;
9291: case REFINER_HEX_2D:
9292: case REFINER_HYBRID_HEX_2D:
9293: if ((p >= vStart) && (p < vEnd)) {
9294: /* Old vertices stay the same */
9295: localPointsNew[m] = vStartNew + (p - vStart);
9296: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9297: remotePointsNew[m].rank = rrank;
9298: ++m;
9299: } else if ((p >= fStart) && (p < fMax)) {
9300: /* Old interior faces add new faces and vertex */
9301: for (r = 0; r < 2; ++r, ++m) {
9302: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
9303: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
9304: remotePointsNew[m].rank = rrank;
9305: }
9306: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
9307: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
9308: remotePointsNew[m].rank = rrank;
9309: ++m;
9310: } else if ((p >= fMax) && (p < fEnd)) {
9311: /* Old hybrid faces stay the same */
9312: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax);
9313: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
9314: remotePointsNew[m].rank = rrank;
9315: ++m;
9316: } else if ((p >= cStart) && (p < cMax)) {
9317: /* Old interior cells add new cells, interior faces, and vertex */
9318: for (r = 0; r < 4; ++r, ++m) {
9319: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9320: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9321: remotePointsNew[m].rank = rrank;
9322: }
9323: for (r = 0; r < 4; ++r, ++m) {
9324: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r;
9325: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
9326: remotePointsNew[m].rank = rrank;
9327: }
9328: localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart);
9329: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
9330: remotePointsNew[m].rank = rrank;
9331: ++m;
9332: } else if ((p >= cStart) && (p < cMax)) {
9333: /* Old hybrid cells add new cells and hybrid face */
9334: for (r = 0; r < 2; ++r, ++m) {
9335: localPointsNew[m] = cStartNew + (p - cStart)*4 + r; /* TODO: is this a bug? */
9336: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; /* TODO: is this a bug? */
9337: remotePointsNew[m].rank = rrank;
9338: }
9339: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
9340: 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]);
9341: remotePointsNew[m].rank = rrank;
9342: ++m;
9343: }
9344: break;
9345: case REFINER_SIMPLEX_3D:
9346: case REFINER_HYBRID_SIMPLEX_3D:
9347: if ((p >= vStart) && (p < vEnd)) {
9348: /* Interior vertices stay the same */
9349: localPointsNew[m] = vStartNew + (p - vStart);
9350: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9351: remotePointsNew[m].rank = rrank;
9352: ++m;
9353: } else if ((p >= eStart) && (p < eMax)) {
9354: /* Interior edges add new edges and vertex */
9355: for (r = 0; r < 2; ++r, ++m) {
9356: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
9357: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
9358: remotePointsNew[m].rank = rrank;
9359: }
9360: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
9361: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
9362: remotePointsNew[m].rank = rrank;
9363: ++m;
9364: } else if ((p >= eMax) && (p < eEnd)) {
9365: /* Hybrid edges stay the same */
9366: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
9367: 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]);
9368: remotePointsNew[m].rank = rrank;
9369: ++m;
9370: } else if ((p >= fStart) && (p < fMax)) {
9371: /* Interior faces add new faces and edges */
9372: for (r = 0; r < 4; ++r, ++m) {
9373: localPointsNew[m] = fStartNew + (p - fStart)*4 + r;
9374: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
9375: remotePointsNew[m].rank = rrank;
9376: }
9377: for (r = 0; r < 3; ++r, ++m) {
9378: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
9379: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
9380: remotePointsNew[m].rank = rrank;
9381: }
9382: } else if ((p >= fMax) && (p < fEnd)) {
9383: /* Hybrid faces add new faces and edges */
9384: for (r = 0; r < 2; ++r, ++m) {
9385: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
9386: 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;
9387: remotePointsNew[m].rank = rrank;
9388: }
9389: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax);
9390: 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]);
9391: remotePointsNew[m].rank = rrank;
9392: ++m;
9393: } else if ((p >= cStart) && (p < cMax)) {
9394: /* Interior cells add new cells, faces, and edges */
9395: for (r = 0; r < 8; ++r, ++m) {
9396: localPointsNew[m] = cStartNew + (p - cStart)*8 + r;
9397: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
9398: remotePointsNew[m].rank = rrank;
9399: }
9400: for (r = 0; r < 8; ++r, ++m) {
9401: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
9402: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
9403: remotePointsNew[m].rank = rrank;
9404: }
9405: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0;
9406: 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;
9407: remotePointsNew[m].rank = rrank;
9408: ++m;
9409: } else if ((p >= cMax) && (p < cEnd)) {
9410: /* Hybrid cells add new cells and faces */
9411: for (r = 0; r < 4; ++r, ++m) {
9412: localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
9413: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
9414: remotePointsNew[m].rank = rrank;
9415: }
9416: for (r = 0; r < 3; ++r, ++m) {
9417: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
9418: 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;
9419: remotePointsNew[m].rank = rrank;
9420: }
9421: }
9422: break;
9423: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9424: case REFINER_SIMPLEX_TO_HEX_3D:
9425: if ((p >= vStart) && (p < vEnd)) {
9426: /* Interior vertices stay the same */
9427: localPointsNew[m] = vStartNew + (p - vStart);
9428: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9429: remotePointsNew[m].rank = rrank;
9430: ++m;
9431: } else if ((p >= eStart) && (p < eMax)) {
9432: /* Interior edges add new edges and vertex */
9433: for (r = 0; r < 2; ++r, ++m) {
9434: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
9435: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
9436: remotePointsNew[m].rank = rrank;
9437: }
9438: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
9439: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
9440: remotePointsNew[m].rank = rrank;
9441: ++m;
9442: } else if ((p >= eMax) && (p < eEnd)) {
9443: /* Hybrid edges stay the same */
9444: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (p - eMax);
9445: 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]);
9446: remotePointsNew[m].rank = rrank;
9447: ++m;
9448: } else if ((p >= fStart) && (p < fMax)) {
9449: /* Interior faces add new faces, edges and a vertex */
9450: for (r = 0; r < 3; ++r, ++m) {
9451: localPointsNew[m] = fStartNew + (p - fStart)*3 + r;
9452: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r;
9453: remotePointsNew[m].rank = rrank;
9454: }
9455: for (r = 0; r < 3; ++r, ++m) {
9456: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
9457: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
9458: remotePointsNew[m].rank = rrank;
9459: }
9460: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
9461: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
9462: remotePointsNew[m].rank = rrank;
9463: ++m;
9464: } else if ((p >= fMax) && (p < fEnd)) {
9465: /* Interior hybrid faces add new faces and an edge */
9466: for (r = 0; r < 2; ++r, ++m) {
9467: localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r;
9468: 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;
9469: remotePointsNew[m].rank = rrank;
9470: }
9471: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax);
9472: 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]);
9473: remotePointsNew[m].rank = rrank;
9474: ++m;
9475: } else if ((p >= cStart) && (p < cMax)) {
9476: /* Interior cells add new cells, faces, edges, and a vertex */
9477: for (r = 0; r < 4; ++r, ++m) {
9478: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9479: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9480: remotePointsNew[m].rank = rrank;
9481: }
9482: for (r = 0; r < 6; ++r, ++m) {
9483: localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r;
9484: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*6 + r;
9485: remotePointsNew[m].rank = rrank;
9486: }
9487: for (r = 0; r < 4; ++r, ++m) {
9488: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r;
9489: 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;
9490: remotePointsNew[m].rank = rrank;
9491: }
9492: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
9493: 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]);
9494: remotePointsNew[m].rank = rrank;
9495: ++m;
9496: } else if ((p >= cMax) && (p < cEnd)) {
9497: /* Interior hybrid cells add new cells, faces and an edge */
9498: for (r = 0; r < 3; ++r, ++m) {
9499: localPointsNew[m] = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r;
9500: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r;
9501: remotePointsNew[m].rank = rrank;
9502: }
9503: for (r = 0; r < 3; ++r, ++m) {
9504: localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
9505: 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;
9506: remotePointsNew[m].rank = rrank;
9507: }
9508: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax);
9509: 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]);
9510: remotePointsNew[m].rank = rrank;
9511: ++m;
9512: }
9513: break;
9514: case REFINER_HEX_3D:
9515: case REFINER_HYBRID_HEX_3D:
9516: if ((p >= vStart) && (p < vEnd)) {
9517: /* Interior vertices stay the same */
9518: localPointsNew[m] = vStartNew + (p - vStart);
9519: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9520: remotePointsNew[m].rank = rrank;
9521: ++m;
9522: } else if ((p >= eStart) && (p < eMax)) {
9523: /* Interior edges add new edges and vertex */
9524: for (r = 0; r < 2; ++r, ++m) {
9525: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
9526: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
9527: remotePointsNew[m].rank = rrank;
9528: }
9529: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
9530: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
9531: remotePointsNew[m].rank = rrank;
9532: ++m;
9533: } else if ((p >= eMax) && (p < eEnd)) {
9534: /* Hybrid edges stay the same */
9535: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
9536: 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]);
9537: remotePointsNew[m].rank = rrank;
9538: ++m;
9539: } else if ((p >= fStart) && (p < fMax)) {
9540: /* Interior faces add new faces, edges, and vertex */
9541: for (r = 0; r < 4; ++r, ++m) {
9542: localPointsNew[m] = fStartNew + (p - fStart)*4 + r;
9543: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
9544: remotePointsNew[m].rank = rrank;
9545: }
9546: for (r = 0; r < 4; ++r, ++m) {
9547: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
9548: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
9549: remotePointsNew[m].rank = rrank;
9550: }
9551: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
9552: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
9553: remotePointsNew[m].rank = rrank;
9554: ++m;
9555: } else if ((p >= fMax) && (p < fEnd)) {
9556: /* Hybrid faces add new faces and edges */
9557: for (r = 0; r < 2; ++r, ++m) {
9558: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
9559: 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;
9560: remotePointsNew[m].rank = rrank;
9561: }
9562: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax);
9563: 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]);
9564: remotePointsNew[m].rank = rrank;
9565: ++m;
9566: } else if ((p >= cStart) && (p < cMax)) {
9567: /* Interior cells add new cells, faces, edges, and vertex */
9568: for (r = 0; r < 8; ++r, ++m) {
9569: localPointsNew[m] = cStartNew + (p - cStart)*8 + r;
9570: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
9571: remotePointsNew[m].rank = rrank;
9572: }
9573: for (r = 0; r < 12; ++r, ++m) {
9574: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
9575: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
9576: remotePointsNew[m].rank = rrank;
9577: }
9578: for (r = 0; r < 6; ++r, ++m) {
9579: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
9580: 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;
9581: remotePointsNew[m].rank = rrank;
9582: }
9583: for (r = 0; r < 1; ++r, ++m) {
9584: localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r;
9585: remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r;
9586: remotePointsNew[m].rank = rrank;
9587: }
9588: } else if ((p >= cMax) && (p < cEnd)) {
9589: /* Hybrid cells add new cells, faces, and edges */
9590: for (r = 0; r < 4; ++r, ++m) {
9591: localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
9592: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
9593: remotePointsNew[m].rank = rrank;
9594: }
9595: for (r = 0; r < 4; ++r, ++m) {
9596: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
9597: 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;
9598: remotePointsNew[m].rank = rrank;
9599: }
9600: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax);
9601: 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]);
9602: remotePointsNew[m].rank = rrank;
9603: ++m;
9604: }
9605: break;
9606: default:
9607: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
9608: }
9609: }
9610: if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew);
9611: ISRestoreIndices(processRanks, &neighbors);
9612: ISDestroy(&processRanks);
9613: {
9614: PetscSFNode *rp, *rtmp;
9615: PetscInt *lp, *idx, *ltmp, i;
9617: /* SF needs sorted leaves to correct calculate Gather */
9618: PetscMalloc1(numLeavesNew,&idx);
9619: PetscMalloc1(numLeavesNew, &lp);
9620: PetscMalloc1(numLeavesNew, &rp);
9621: for (i = 0; i < numLeavesNew; ++i) {
9622: 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);
9623: idx[i] = i;
9624: }
9625: PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);
9626: for (i = 0; i < numLeavesNew; ++i) {
9627: lp[i] = localPointsNew[idx[i]];
9628: rp[i] = remotePointsNew[idx[i]];
9629: }
9630: ltmp = localPointsNew;
9631: localPointsNew = lp;
9632: rtmp = remotePointsNew;
9633: remotePointsNew = rp;
9634: PetscFree(idx);
9635: PetscFree(ltmp);
9636: PetscFree(rtmp);
9637: }
9638: PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);
9639: PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);
9640: PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);
9641: return(0);
9642: }
9644: static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
9645: {
9646: PetscInt numLabels, l;
9647: PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
9648: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
9652: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
9653: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
9654: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
9655: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
9656: DMPlexGetDepth(dm, &depth);
9657: if (refiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
9658: DMGetNumLabels(dm, &numLabels);
9659: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
9660: switch (refiner) {
9661: case REFINER_NOOP:
9662: case REFINER_SIMPLEX_1D:
9663: case REFINER_SIMPLEX_2D:
9664: case REFINER_SIMPLEX_TO_HEX_2D:
9665: case REFINER_HEX_2D:
9666: case REFINER_SIMPLEX_3D:
9667: case REFINER_HEX_3D:
9668: case REFINER_SIMPLEX_TO_HEX_3D:
9669: break;
9670: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9671: case REFINER_HYBRID_SIMPLEX_3D:
9672: case REFINER_HYBRID_HEX_3D:
9673: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
9674: case REFINER_HYBRID_SIMPLEX_2D:
9675: case REFINER_HYBRID_HEX_2D:
9676: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
9677: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9678: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
9679: break;
9680: default:
9681: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
9682: }
9683: cMax = cMax < 0 ? cEnd : cMax;
9684: fMax = fMax < 0 ? fEnd : fMax;
9685: eMax = eMax < 0 ? eEnd : eMax;
9686: for (l = 0; l < numLabels; ++l) {
9687: DMLabel label, labelNew;
9688: const char *lname;
9689: PetscBool isDepth;
9690: IS valueIS;
9691: const PetscInt *values;
9692: PetscInt defVal;
9693: PetscInt numValues, val;
9695: DMGetLabelName(dm, l, &lname);
9696: PetscStrcmp(lname, "depth", &isDepth);
9697: if (isDepth) continue;
9698: DMCreateLabel(rdm, lname);
9699: DMGetLabel(dm, lname, &label);
9700: DMGetLabel(rdm, lname, &labelNew);
9701: DMLabelGetDefaultValue(label,&defVal);
9702: DMLabelSetDefaultValue(labelNew,defVal);
9703: DMLabelGetValueIS(label, &valueIS);
9704: ISGetLocalSize(valueIS, &numValues);
9705: ISGetIndices(valueIS, &values);
9706: for (val = 0; val < numValues; ++val) {
9707: IS pointIS;
9708: const PetscInt *points;
9709: PetscInt numPoints, n;
9711: DMLabelGetStratumIS(label, values[val], &pointIS);
9712: ISGetLocalSize(pointIS, &numPoints);
9713: ISGetIndices(pointIS, &points);
9714: /* Ensure refined label is created with same number of strata as
9715: * original (even if no entries here). */
9716: DMLabelAddStratum(labelNew, values[val]);
9717: for (n = 0; n < numPoints; ++n) {
9718: const PetscInt p = points[n];
9719: switch (refiner) {
9720: case REFINER_SIMPLEX_1D:
9721: if ((p >= vStart) && (p < vEnd)) {
9722: /* Old vertices stay the same */
9723: newp = vStartNew + (p - vStart);
9724: DMLabelSetValue(labelNew, newp, values[val]);
9725: } else if ((p >= cStart) && (p < cEnd)) {
9726: /* Old cells add new cells and vertex */
9727: newp = vStartNew + (vEnd - vStart) + (p - cStart);
9728: DMLabelSetValue(labelNew, newp, values[val]);
9729: for (r = 0; r < 2; ++r) {
9730: newp = cStartNew + (p - cStart)*2 + r;
9731: DMLabelSetValue(labelNew, newp, values[val]);
9732: }
9733: }
9734: break;
9735: case REFINER_SIMPLEX_2D:
9736: if ((p >= vStart) && (p < vEnd)) {
9737: /* Old vertices stay the same */
9738: newp = vStartNew + (p - vStart);
9739: DMLabelSetValue(labelNew, newp, values[val]);
9740: } else if ((p >= fStart) && (p < fEnd)) {
9741: /* Old faces add new faces and vertex */
9742: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9743: DMLabelSetValue(labelNew, newp, values[val]);
9744: for (r = 0; r < 2; ++r) {
9745: newp = fStartNew + (p - fStart)*2 + r;
9746: DMLabelSetValue(labelNew, newp, values[val]);
9747: }
9748: } else if ((p >= cStart) && (p < cEnd)) {
9749: /* Old cells add new cells and interior faces */
9750: for (r = 0; r < 4; ++r) {
9751: newp = cStartNew + (p - cStart)*4 + r;
9752: DMLabelSetValue(labelNew, newp, values[val]);
9753: }
9754: for (r = 0; r < 3; ++r) {
9755: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9756: DMLabelSetValue(labelNew, newp, values[val]);
9757: }
9758: }
9759: break;
9760: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9761: case REFINER_SIMPLEX_TO_HEX_2D:
9762: if ((p >= vStart) && (p < vEnd)) {
9763: /* Old vertices stay the same */
9764: newp = vStartNew + (p - vStart);
9765: DMLabelSetValue(labelNew, newp, values[val]);
9766: } else if ((p >= fStart) && (p < fEnd)) {
9767: /* Old faces add new faces and vertex */
9768: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9769: DMLabelSetValue(labelNew, newp, values[val]);
9770: for (r = 0; r < 2; ++r) {
9771: newp = fStartNew + (p - fStart)*2 + r;
9772: DMLabelSetValue(labelNew, newp, values[val]);
9773: }
9774: } else if ((p >= cStart) && (p < cMax)) {
9775: /* Old cells add new cells, interior faces, and a vertex */
9776: for (r = 0; r < 3; ++r) {
9777: newp = cStartNew + (p - cStart)*3 + r;
9778: DMLabelSetValue(labelNew, newp, values[val]);
9779: }
9780: for (r = 0; r < 3; ++r) {
9781: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9782: DMLabelSetValue(labelNew, newp, values[val]);
9783: }
9784: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p;
9785: DMLabelSetValue(labelNew, newp, values[val]);
9786: } else if ((p >= cMax) && (p < cEnd)) {
9787: /* Old hybrid cells add new cells, interior faces, and a vertex */
9788: for (r = 0; r < 4; ++r) {
9789: newp = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r;
9790: DMLabelSetValue(labelNew, newp, values[val]);
9791: }
9792: for (r = 0; r < 4; ++r) {
9793: newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r;
9794: DMLabelSetValue(labelNew, newp, values[val]);
9795: }
9796: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p;
9797: DMLabelSetValue(labelNew, newp, values[val]);
9798: }
9799: break;
9800: case REFINER_HEX_2D:
9801: if ((p >= vStart) && (p < vEnd)) {
9802: /* Old vertices stay the same */
9803: newp = vStartNew + (p - vStart);
9804: DMLabelSetValue(labelNew, newp, values[val]);
9805: } else if ((p >= fStart) && (p < fEnd)) {
9806: /* Old faces add new faces and vertex */
9807: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9808: DMLabelSetValue(labelNew, newp, values[val]);
9809: for (r = 0; r < 2; ++r) {
9810: newp = fStartNew + (p - fStart)*2 + r;
9811: DMLabelSetValue(labelNew, newp, values[val]);
9812: }
9813: } else if ((p >= cStart) && (p < cEnd)) {
9814: /* Old cells add new cells and interior faces and vertex */
9815: for (r = 0; r < 4; ++r) {
9816: newp = cStartNew + (p - cStart)*4 + r;
9817: DMLabelSetValue(labelNew, newp, values[val]);
9818: }
9819: for (r = 0; r < 4; ++r) {
9820: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
9821: DMLabelSetValue(labelNew, newp, values[val]);
9822: }
9823: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9824: DMLabelSetValue(labelNew, newp, values[val]);
9825: }
9826: break;
9827: case REFINER_HYBRID_SIMPLEX_2D:
9828: if ((p >= vStart) && (p < vEnd)) {
9829: /* Old vertices stay the same */
9830: newp = vStartNew + (p - vStart);
9831: DMLabelSetValue(labelNew, newp, values[val]);
9832: } else if ((p >= fStart) && (p < fMax)) {
9833: /* Old interior faces add new faces and vertex */
9834: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9835: DMLabelSetValue(labelNew, newp, values[val]);
9836: for (r = 0; r < 2; ++r) {
9837: newp = fStartNew + (p - fStart)*2 + r;
9838: DMLabelSetValue(labelNew, newp, values[val]);
9839: }
9840: } else if ((p >= fMax) && (p < fEnd)) {
9841: /* Old hybrid faces stay the same */
9842: newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
9843: DMLabelSetValue(labelNew, newp, values[val]);
9844: } else if ((p >= cStart) && (p < cMax)) {
9845: /* Old interior cells add new cells and interior faces */
9846: for (r = 0; r < 4; ++r) {
9847: newp = cStartNew + (p - cStart)*4 + r;
9848: DMLabelSetValue(labelNew, newp, values[val]);
9849: }
9850: for (r = 0; r < 3; ++r) {
9851: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9852: DMLabelSetValue(labelNew, newp, values[val]);
9853: }
9854: } else if ((p >= cMax) && (p < cEnd)) {
9855: /* Old hybrid cells add new cells and hybrid face */
9856: for (r = 0; r < 2; ++r) {
9857: newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
9858: DMLabelSetValue(labelNew, newp, values[val]);
9859: }
9860: newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
9861: DMLabelSetValue(labelNew, newp, values[val]);
9862: }
9863: break;
9864: case REFINER_HYBRID_HEX_2D:
9865: if ((p >= vStart) && (p < vEnd)) {
9866: /* Old vertices stay the same */
9867: newp = vStartNew + (p - vStart);
9868: DMLabelSetValue(labelNew, newp, values[val]);
9869: } else if ((p >= fStart) && (p < fMax)) {
9870: /* Old interior faces add new faces and vertex */
9871: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9872: DMLabelSetValue(labelNew, newp, values[val]);
9873: for (r = 0; r < 2; ++r) {
9874: newp = fStartNew + (p - fStart)*2 + r;
9875: DMLabelSetValue(labelNew, newp, values[val]);
9876: }
9877: } else if ((p >= fMax) && (p < fEnd)) {
9878: /* Old hybrid faces stay the same */
9879: newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
9880: DMLabelSetValue(labelNew, newp, values[val]);
9881: } else if ((p >= cStart) && (p < cMax)) {
9882: /* Old interior cells add new cells, interior faces, and vertex */
9883: for (r = 0; r < 4; ++r) {
9884: newp = cStartNew + (p - cStart)*4 + r;
9885: DMLabelSetValue(labelNew, newp, values[val]);
9886: }
9887: for (r = 0; r < 4; ++r) {
9888: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
9889: DMLabelSetValue(labelNew, newp, values[val]);
9890: }
9891: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9892: DMLabelSetValue(labelNew, newp, values[val]);
9893: } else if ((p >= cMax) && (p < cEnd)) {
9894: /* Old hybrid cells add new cells and hybrid face */
9895: for (r = 0; r < 2; ++r) {
9896: newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
9897: DMLabelSetValue(labelNew, newp, values[val]);
9898: }
9899: newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
9900: DMLabelSetValue(labelNew, newp, values[val]);
9901: }
9902: break;
9903: case REFINER_SIMPLEX_3D:
9904: if ((p >= vStart) && (p < vEnd)) {
9905: /* Old vertices stay the same */
9906: newp = vStartNew + (p - vStart);
9907: DMLabelSetValue(labelNew, newp, values[val]);
9908: } else if ((p >= eStart) && (p < eEnd)) {
9909: /* Old edges add new edges and vertex */
9910: for (r = 0; r < 2; ++r) {
9911: newp = eStartNew + (p - eStart)*2 + r;
9912: DMLabelSetValue(labelNew, newp, values[val]);
9913: }
9914: newp = vStartNew + (vEnd - vStart) + (p - eStart);
9915: DMLabelSetValue(labelNew, newp, values[val]);
9916: } else if ((p >= fStart) && (p < fEnd)) {
9917: /* Old faces add new faces and edges */
9918: for (r = 0; r < 4; ++r) {
9919: newp = fStartNew + (p - fStart)*4 + r;
9920: DMLabelSetValue(labelNew, newp, values[val]);
9921: }
9922: for (r = 0; r < 3; ++r) {
9923: newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
9924: DMLabelSetValue(labelNew, newp, values[val]);
9925: }
9926: } else if ((p >= cStart) && (p < cEnd)) {
9927: /* Old cells add new cells and interior faces and edges */
9928: for (r = 0; r < 8; ++r) {
9929: newp = cStartNew + (p - cStart)*8 + r;
9930: DMLabelSetValue(labelNew, newp, values[val]);
9931: }
9932: for (r = 0; r < 8; ++r) {
9933: newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
9934: DMLabelSetValue(labelNew, newp, values[val]);
9935: }
9936: for (r = 0; r < 1; ++r) {
9937: newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
9938: DMLabelSetValue(labelNew, newp, values[val]);
9939: }
9940: }
9941: break;
9942: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9943: case REFINER_SIMPLEX_TO_HEX_3D:
9944: if ((p >= vStart) && (p < vEnd)) {
9945: /* Old vertices stay the same */
9946: newp = vStartNew + (p - vStart);
9947: DMLabelSetValue(labelNew, newp, values[val]);
9948: } else if ((p >= eStart) && (p < eMax)) {
9949: /* Interior edges add new edges and vertex */
9950: for (r = 0; r < 2; ++r) {
9951: newp = eStartNew + (p - eStart)*2 + r;
9952: DMLabelSetValue(labelNew, newp, values[val]);
9953: }
9954: newp = vStartNew + (vEnd - vStart) + (p - eStart);
9955: DMLabelSetValue(labelNew, newp, values[val]);
9956: } else if ((p >= eMax) && (p < eEnd)) {
9957: /* Hybrid edges stay the same */
9958: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + p - eMax;
9959: DMLabelSetValue(labelNew, newp, values[val]);
9960: } else if ((p >= fStart) && (p < fMax)) {
9961: /* Old faces add new faces, edges and a vertex */
9962: for (r = 0; r < 3; ++r) {
9963: newp = fStartNew + (p - fStart)*3 + r;
9964: DMLabelSetValue(labelNew, newp, values[val]);
9965: }
9966: for (r = 0; r < 3; ++r) {
9967: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
9968: DMLabelSetValue(labelNew, newp, values[val]);
9969: }
9970: } else if ((p >= fMax) && (p < fEnd)) {
9971: /* Old hybrid faces add new faces and an edge */
9972: for (r = 0; r < 2; ++r) {
9973: newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r;
9974: DMLabelSetValue(labelNew, newp, values[val]);
9975: }
9976: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax);
9977: DMLabelSetValue(labelNew, newp, values[val]);
9978: } else if ((p >= cStart) && (p < cMax)) {
9979: /* Old cells add new cells and interior faces and edges and a vertex */
9980: for (r = 0; r < 4; ++r) {
9981: newp = cStartNew + (p - cStart)*4 + r;
9982: DMLabelSetValue(labelNew, newp, values[val]);
9983: }
9984: for (r = 0; r < 6; ++r) {
9985: newp = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r;
9986: DMLabelSetValue(labelNew, newp, values[val]);
9987: }
9988: for (r = 0; r < 4; ++r) {
9989: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r;
9990: DMLabelSetValue(labelNew, newp, values[val]);
9991: }
9992: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + p - cStart;
9993: DMLabelSetValue(labelNew, newp, values[val]);
9994: } else if ((p >= cMax) && (p < cEnd)) {
9995: /* Old hybrid cells add new cells and interior faces and an edge */
9996: for (r = 0; r < 3; ++r) {
9997: newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r;
9998: DMLabelSetValue(labelNew, newp, values[val]);
9999: }
10000: for (r = 0; r < 3; ++r) {
10001: newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
10002: DMLabelSetValue(labelNew, newp, values[val]);
10003: }
10004: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + p - cMax;
10005: DMLabelSetValue(labelNew, newp, values[val]);
10006: }
10007: break;
10008: case REFINER_HYBRID_SIMPLEX_3D:
10009: if ((p >= vStart) && (p < vEnd)) {
10010: /* Interior vertices stay the same */
10011: newp = vStartNew + (p - vStart);
10012: DMLabelSetValue(labelNew, newp, values[val]);
10013: } else if ((p >= eStart) && (p < eMax)) {
10014: /* Interior edges add new edges and vertex */
10015: for (r = 0; r < 2; ++r) {
10016: newp = eStartNew + (p - eStart)*2 + r;
10017: DMLabelSetValue(labelNew, newp, values[val]);
10018: }
10019: newp = vStartNew + (vEnd - vStart) + (p - eStart);
10020: DMLabelSetValue(labelNew, newp, values[val]);
10021: } else if ((p >= eMax) && (p < eEnd)) {
10022: /* Hybrid edges stay the same */
10023: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
10024: DMLabelSetValue(labelNew, newp, values[val]);
10025: } else if ((p >= fStart) && (p < fMax)) {
10026: /* Interior faces add new faces and edges */
10027: for (r = 0; r < 4; ++r) {
10028: newp = fStartNew + (p - fStart)*4 + r;
10029: DMLabelSetValue(labelNew, newp, values[val]);
10030: }
10031: for (r = 0; r < 3; ++r) {
10032: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
10033: DMLabelSetValue(labelNew, newp, values[val]);
10034: }
10035: } else if ((p >= fMax) && (p < fEnd)) {
10036: /* Hybrid faces add new faces and edges */
10037: for (r = 0; r < 2; ++r) {
10038: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
10039: DMLabelSetValue(labelNew, newp, values[val]);
10040: }
10041: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
10042: DMLabelSetValue(labelNew, newp, values[val]);
10043: } else if ((p >= cStart) && (p < cMax)) {
10044: /* Interior cells add new cells, faces, and edges */
10045: for (r = 0; r < 8; ++r) {
10046: newp = cStartNew + (p - cStart)*8 + r;
10047: DMLabelSetValue(labelNew, newp, values[val]);
10048: }
10049: for (r = 0; r < 8; ++r) {
10050: newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
10051: DMLabelSetValue(labelNew, newp, values[val]);
10052: }
10053: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
10054: DMLabelSetValue(labelNew, newp, values[val]);
10055: } else if ((p >= cMax) && (p < cEnd)) {
10056: /* Hybrid cells add new cells and faces */
10057: for (r = 0; r < 4; ++r) {
10058: newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
10059: DMLabelSetValue(labelNew, newp, values[val]);
10060: }
10061: for (r = 0; r < 3; ++r) {
10062: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
10063: DMLabelSetValue(labelNew, newp, values[val]);
10064: }
10065: }
10066: break;
10067: case REFINER_HEX_3D:
10068: if ((p >= vStart) && (p < vEnd)) {
10069: /* Old vertices stay the same */
10070: newp = vStartNew + (p - vStart);
10071: DMLabelSetValue(labelNew, newp, values[val]);
10072: } else if ((p >= eStart) && (p < eEnd)) {
10073: /* Old edges add new edges and vertex */
10074: for (r = 0; r < 2; ++r) {
10075: newp = eStartNew + (p - eStart)*2 + r;
10076: DMLabelSetValue(labelNew, newp, values[val]);
10077: }
10078: newp = vStartNew + (vEnd - vStart) + (p - eStart);
10079: DMLabelSetValue(labelNew, newp, values[val]);
10080: } else if ((p >= fStart) && (p < fEnd)) {
10081: /* Old faces add new faces, edges, and vertex */
10082: for (r = 0; r < 4; ++r) {
10083: newp = fStartNew + (p - fStart)*4 + r;
10084: DMLabelSetValue(labelNew, newp, values[val]);
10085: }
10086: for (r = 0; r < 4; ++r) {
10087: newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
10088: DMLabelSetValue(labelNew, newp, values[val]);
10089: }
10090: newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
10091: DMLabelSetValue(labelNew, newp, values[val]);
10092: } else if ((p >= cStart) && (p < cEnd)) {
10093: /* Old cells add new cells, faces, edges, and vertex */
10094: for (r = 0; r < 8; ++r) {
10095: newp = cStartNew + (p - cStart)*8 + r;
10096: DMLabelSetValue(labelNew, newp, values[val]);
10097: }
10098: for (r = 0; r < 12; ++r) {
10099: newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
10100: DMLabelSetValue(labelNew, newp, values[val]);
10101: }
10102: for (r = 0; r < 6; ++r) {
10103: newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
10104: DMLabelSetValue(labelNew, newp, values[val]);
10105: }
10106: newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
10107: DMLabelSetValue(labelNew, newp, values[val]);
10108: }
10109: break;
10110: case REFINER_HYBRID_HEX_3D:
10111: if ((p >= vStart) && (p < vEnd)) {
10112: /* Interior vertices stay the same */
10113: newp = vStartNew + (p - vStart);
10114: DMLabelSetValue(labelNew, newp, values[val]);
10115: } else if ((p >= eStart) && (p < eMax)) {
10116: /* Interior edges add new edges and vertex */
10117: for (r = 0; r < 2; ++r) {
10118: newp = eStartNew + (p - eStart)*2 + r;
10119: DMLabelSetValue(labelNew, newp, values[val]);
10120: }
10121: newp = vStartNew + (vEnd - vStart) + (p - eStart);
10122: DMLabelSetValue(labelNew, newp, values[val]);
10123: } else if ((p >= eMax) && (p < eEnd)) {
10124: /* Hybrid edges stay the same */
10125: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
10126: DMLabelSetValue(labelNew, newp, values[val]);
10127: } else if ((p >= fStart) && (p < fMax)) {
10128: /* Interior faces add new faces, edges, and vertex */
10129: for (r = 0; r < 4; ++r) {
10130: newp = fStartNew + (p - fStart)*4 + r;
10131: DMLabelSetValue(labelNew, newp, values[val]);
10132: }
10133: for (r = 0; r < 4; ++r) {
10134: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
10135: DMLabelSetValue(labelNew, newp, values[val]);
10136: }
10137: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
10138: DMLabelSetValue(labelNew, newp, values[val]);
10139: } else if ((p >= fMax) && (p < fEnd)) {
10140: /* Hybrid faces add new faces and edges */
10141: for (r = 0; r < 2; ++r) {
10142: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
10143: DMLabelSetValue(labelNew, newp, values[val]);
10144: }
10145: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
10146: DMLabelSetValue(labelNew, newp, values[val]);
10147: } else if ((p >= cStart) && (p < cMax)) {
10148: /* Interior cells add new cells, faces, edges, and vertex */
10149: for (r = 0; r < 8; ++r) {
10150: newp = cStartNew + (p - cStart)*8 + r;
10151: DMLabelSetValue(labelNew, newp, values[val]);
10152: }
10153: for (r = 0; r < 12; ++r) {
10154: newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
10155: DMLabelSetValue(labelNew, newp, values[val]);
10156: }
10157: for (r = 0; r < 6; ++r) {
10158: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
10159: DMLabelSetValue(labelNew, newp, values[val]);
10160: }
10161: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
10162: DMLabelSetValue(labelNew, newp, values[val]);
10163: } else if ((p >= cMax) && (p < cEnd)) {
10164: /* Hybrid cells add new cells, faces, and edges */
10165: for (r = 0; r < 4; ++r) {
10166: newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
10167: DMLabelSetValue(labelNew, newp, values[val]);
10168: }
10169: for (r = 0; r < 4; ++r) {
10170: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
10171: DMLabelSetValue(labelNew, newp, values[val]);
10172: }
10173: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
10174: DMLabelSetValue(labelNew, newp, values[val]);
10175: }
10176: break;
10177: default:
10178: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
10179: }
10180: }
10181: ISRestoreIndices(pointIS, &points);
10182: ISDestroy(&pointIS);
10183: }
10184: ISRestoreIndices(valueIS, &values);
10185: ISDestroy(&valueIS);
10186: }
10187: return(0);
10188: }
10190: /* This will only work for interpolated meshes */
10191: PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
10192: {
10193: DM rdm;
10194: PetscInt *depthSize;
10195: PetscInt dim, embedDim, depth = 0, d, pStart = 0, pEnd = 0;
10199: DMCreate(PetscObjectComm((PetscObject)dm), &rdm);
10200: DMSetType(rdm, DMPLEX);
10201: DMGetDimension(dm, &dim);
10202: DMSetDimension(rdm, dim);
10203: DMGetCoordinateDim(dm, &embedDim);
10204: DMSetCoordinateDim(rdm, embedDim);
10205: /* Calculate number of new points of each depth */
10206: DMPlexGetDepth(dm, &depth);
10207: if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
10208: PetscMalloc1(depth+1, &depthSize);
10209: PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));
10210: CellRefinerGetSizes(cellRefiner, dm, depthSize);
10211: /* Step 1: Set chart */
10212: for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
10213: DMPlexSetChart(rdm, pStart, pEnd);
10214: /* Step 2: Set cone/support sizes (automatically stratifies) */
10215: CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);
10216: /* Step 3: Setup refined DM */
10217: DMSetUp(rdm);
10218: /* Step 4: Set cones and supports (automatically symmetrizes) */
10219: CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);
10220: /* Step 5: Create pointSF */
10221: CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);
10222: /* Step 6: Create labels */
10223: CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);
10224: /* Step 7: Set coordinates */
10225: CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);
10226: PetscFree(depthSize);
10228: *dmRefined = rdm;
10229: return(0);
10230: }
10232: /*@
10233: DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
10235: Input Parameter:
10236: . dm - The coarse DM
10238: Output Parameter:
10239: . fpointIS - The IS of all the fine points which exist in the original coarse mesh
10241: Level: developer
10243: .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
10244: @*/
10245: PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
10246: {
10247: CellRefiner cellRefiner;
10248: PetscInt *depthSize, *fpoints;
10249: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
10250: PetscInt depth, pStart, pEnd, p, vStart, vEnd, v;
10254: DMPlexGetDepth(dm, &depth);
10255: DMPlexGetChart(dm, &pStart, &pEnd);
10256: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
10257: DMPlexGetCellRefiner_Internal(dm, &cellRefiner);
10258: PetscMalloc1(depth+1, &depthSize);
10259: CellRefinerGetSizes(cellRefiner, dm, depthSize);
10260: if (cellRefiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
10261: PetscMalloc1(pEnd-pStart,&fpoints);
10262: for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
10263: switch (cellRefiner) {
10264: case REFINER_SIMPLEX_1D:
10265: case REFINER_SIMPLEX_2D:
10266: case REFINER_HYBRID_SIMPLEX_2D:
10267: case REFINER_HEX_2D:
10268: case REFINER_HYBRID_HEX_2D:
10269: case REFINER_SIMPLEX_3D:
10270: case REFINER_HYBRID_SIMPLEX_3D:
10271: case REFINER_HEX_3D:
10272: case REFINER_HYBRID_HEX_3D:
10273: for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
10274: break;
10275: default:
10276: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[cellRefiner]);
10277: }
10278: ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);
10279: PetscFree(depthSize);
10280: return(0);
10281: }
10283: /*@
10284: DMPlexSetRefinementUniform - Set the flag for uniform refinement
10286: Input Parameters:
10287: + dm - The DM
10288: - refinementUniform - The flag for uniform refinement
10290: Level: developer
10292: .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10293: @*/
10294: PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
10295: {
10296: DM_Plex *mesh = (DM_Plex*) dm->data;
10300: mesh->refinementUniform = refinementUniform;
10301: return(0);
10302: }
10304: /*@
10305: DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
10307: Input Parameter:
10308: . dm - The DM
10310: Output Parameter:
10311: . refinementUniform - The flag for uniform refinement
10313: Level: developer
10315: .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10316: @*/
10317: PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
10318: {
10319: DM_Plex *mesh = (DM_Plex*) dm->data;
10324: *refinementUniform = mesh->refinementUniform;
10325: return(0);
10326: }
10328: /*@
10329: DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
10331: Input Parameters:
10332: + dm - The DM
10333: - refinementLimit - The maximum cell volume in the refined mesh
10335: Level: developer
10337: .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
10338: @*/
10339: PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
10340: {
10341: DM_Plex *mesh = (DM_Plex*) dm->data;
10345: mesh->refinementLimit = refinementLimit;
10346: return(0);
10347: }
10349: /*@
10350: DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
10352: Input Parameter:
10353: . dm - The DM
10355: Output Parameter:
10356: . refinementLimit - The maximum cell volume in the refined mesh
10358: Level: developer
10360: .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
10361: @*/
10362: PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
10363: {
10364: DM_Plex *mesh = (DM_Plex*) dm->data;
10369: /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
10370: *refinementLimit = mesh->refinementLimit;
10371: return(0);
10372: }
10374: /*@
10375: DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
10377: Input Parameters:
10378: + dm - The DM
10379: - refinementFunc - Function giving the maximum cell volume in the refined mesh
10381: Note: The calling sequence is refinementFunc(coords, limit)
10382: $ coords - Coordinates of the current point, usually a cell centroid
10383: $ limit - The maximum cell volume for a cell containing this point
10385: Level: developer
10387: .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10388: @*/
10389: PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
10390: {
10391: DM_Plex *mesh = (DM_Plex*) dm->data;
10395: mesh->refinementFunc = refinementFunc;
10396: return(0);
10397: }
10399: /*@
10400: DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
10402: Input Parameter:
10403: . dm - The DM
10405: Output Parameter:
10406: . refinementFunc - Function giving the maximum cell volume in the refined mesh
10408: Note: The calling sequence is refinementFunc(coords, limit)
10409: $ coords - Coordinates of the current point, usually a cell centroid
10410: $ limit - The maximum cell volume for a cell containing this point
10412: Level: developer
10414: .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10415: @*/
10416: PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
10417: {
10418: DM_Plex *mesh = (DM_Plex*) dm->data;
10423: *refinementFunc = mesh->refinementFunc;
10424: return(0);
10425: }
10427: PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
10428: {
10429: PetscInt dim, cStart, cEnd, coneSize, cMax, fMax;
10433: DMGetDimension(dm, &dim);
10434: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
10435: if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; return(0);}
10436: DMPlexGetConeSize(dm, cStart, &coneSize);
10437: DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);
10438: switch (dim) {
10439: case 1:
10440: switch (coneSize) {
10441: case 2:
10442: *cellRefiner = REFINER_SIMPLEX_1D;
10443: break;
10444: default:
10445: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10446: }
10447: break;
10448: case 2:
10449: switch (coneSize) {
10450: case 3:
10451: if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D;
10452: else *cellRefiner = REFINER_SIMPLEX_2D;
10453: break;
10454: case 4:
10455: if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D;
10456: else *cellRefiner = REFINER_HEX_2D;
10457: break;
10458: default:
10459: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10460: }
10461: break;
10462: case 3:
10463: switch (coneSize) {
10464: case 4:
10465: if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
10466: else *cellRefiner = REFINER_SIMPLEX_3D;
10467: break;
10468: case 5:
10469: if (cMax == 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
10470: else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10471: break;
10472: case 6:
10473: if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D;
10474: else *cellRefiner = REFINER_HEX_3D;
10475: break;
10476: default:
10477: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10478: }
10479: break;
10480: default:
10481: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %D for cell refiner", dim);
10482: }
10483: return(0);
10484: }
10486: PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined)
10487: {
10488: PetscBool isUniform;
10492: DMPlexGetRefinementUniform(dm, &isUniform);
10493: if (isUniform) {
10494: CellRefiner cellRefiner;
10495: PetscBool localized;
10497: DMGetCoordinatesLocalized(dm, &localized);
10498: DMPlexGetCellRefiner_Internal(dm, &cellRefiner);
10499: DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);
10500: DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);
10501: DMCopyBoundary(dm, *dmRefined);
10502: if (localized) {DMLocalizeCoordinates(*dmRefined);}
10503: } else {
10504: DMPlexRefine_Internal(dm, NULL, dmRefined);
10505: }
10506: return(0);
10507: }
10509: PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[])
10510: {
10511: DM cdm = dm;
10512: PetscInt r;
10513: PetscBool isUniform, localized;
10517: DMPlexGetRefinementUniform(dm, &isUniform);
10518: DMGetCoordinatesLocalized(dm, &localized);
10519: if (isUniform) {
10520: for (r = 0; r < nlevels; ++r) {
10521: CellRefiner cellRefiner;
10523: DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);
10524: DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);
10525: DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);
10526: DMSetRefineLevel(dmRefined[r], cdm->levelup+1);
10527: DMCopyBoundary(cdm, dmRefined[r]);
10528: if (localized) {DMLocalizeCoordinates(dmRefined[r]);}
10529: DMSetCoarseDM(dmRefined[r], cdm);
10530: DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);
10531: cdm = dmRefined[r];
10532: }
10533: } else {
10534: for (r = 0; r < nlevels; ++r) {
10535: DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);
10536: DMCopyBoundary(cdm, dmRefined[r]);
10537: if (localized) {DMLocalizeCoordinates(dmRefined[r]);}
10538: DMSetCoarseDM(dmRefined[r], cdm);
10539: cdm = dmRefined[r];
10540: }
10541: }
10542: return(0);
10543: }