Actual source code: plexrefine.c
petsc-3.12.0 2019-09-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: break;
251: dim = 3;
252: if (numSubcells) *numSubcells = 8;
253: if (v0) {
254: PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);
255: /* A */
256: v[0+0] = -1.0; v[0+1] = -1.0; v[0+2] = -1.0;
257: j[0+0] = 0.5; j[0+1] = 0.0; j[0+2] = 0.0;
258: j[0+3] = 0.0; j[0+4] = 0.5; j[0+5] = 0.0;
259: j[0+6] = 0.0; j[0+7] = 0.0; j[0+8] = 0.5;
260: /* B */
261: v[3+0] = -1.0; v[3+1] = 0.0; v[3+2] = -1.0;
262: j[9+0] = 0.5; j[9+1] = 0.0; j[9+2] = 0.0;
263: j[9+3] = 0.0; j[9+4] = 0.5; j[9+5] = 0.0;
264: j[9+6] = 0.0; j[9+7] = 0.0; j[9+8] = 0.5;
265: /* C */
266: v[6+0] = 0.0; v[6+1] = 0.0; v[6+2] = -1.0;
267: j[18+0] = 0.5; j[18+1] = 0.0; j[18+2] = 0.0;
268: j[18+3] = 0.0; j[18+4] = 0.5; j[18+5] = 0.0;
269: j[18+6] = 0.0; j[18+7] = 0.0; j[18+8] = 0.5;
270: /* D */
271: v[9+0] = 0.0; v[9+1] = -1.0; v[9+2] = -1.0;
272: j[27+0] = 0.5; j[27+1] = 0.0; j[27+2] = 0.0;
273: j[27+3] = 0.0; j[27+4] = 0.5; j[27+5] = 0.0;
274: j[27+6] = 0.0; j[27+7] = 0.0; j[27+8] = 0.5;
275: /* E */
276: v[12+0] = -1.0; v[12+1] = -1.0; v[12+2] = 0.0;
277: j[36+0] = 0.5; j[36+1] = 0.0; j[36+2] = 0.0;
278: j[36+3] = 0.0; j[36+4] = 0.5; j[36+5] = 0.0;
279: j[36+6] = 0.0; j[36+7] = 0.0; j[36+8] = 0.5;
280: /* F */
281: v[15+0] = 0.0; v[15+1] = -1.0; v[15+2] = 0.0;
282: j[45+0] = 0.5; j[45+1] = 0.0; j[45+2] = 0.0;
283: j[45+3] = 0.0; j[45+4] = 0.5; j[45+5] = 0.0;
284: j[45+6] = 0.0; j[45+7] = 0.0; j[45+8] = 0.5;
285: /* G */
286: v[18+0] = 0.0; v[18+1] = 0.0; v[18+2] = 0.0;
287: j[54+0] = 0.5; j[54+1] = 0.0; j[54+2] = 0.0;
288: j[54+3] = 0.0; j[54+4] = 0.5; j[54+5] = 0.0;
289: j[54+6] = 0.0; j[54+7] = 0.0; j[54+8] = 0.5;
290: /* H */
291: v[21+0] = -1.0; v[21+1] = 0.0; v[21+2] = 0.0;
292: j[63+0] = 0.5; j[63+1] = 0.0; j[63+2] = 0.0;
293: j[63+3] = 0.0; j[63+4] = 0.5; j[63+5] = 0.0;
294: j[63+6] = 0.0; j[63+7] = 0.0; j[63+8] = 0.5;
295: for (s = 0; s < 8; ++s) {
296: DMPlex_Det3D_Internal(&detJ, &j[s*dim*dim]);
297: DMPlex_Invert3D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
298: }
299: }
300: default:
301: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
302: }
303: if (v0) {*v0 = v; *jac = j; *invjac = invj;}
304: 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: default:
337: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
338: }
339: return(0);
340: }
342: static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
343: {
344: PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
348: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
349: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
350: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
351: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
352: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
353: switch (refiner) {
354: case REFINER_NOOP:
355: break;
356: case REFINER_SIMPLEX_1D:
357: depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */
358: depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */
359: break;
360: case REFINER_SIMPLEX_2D:
361: depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */
362: depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */
363: depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
364: break;
365: case REFINER_HYBRID_SIMPLEX_2D:
366: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
367: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
368: depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */
369: depthSize[1] = 2*(fMax - fStart) + 3*(cMax - cStart) + (fEnd - fMax) + (cEnd - cMax); /* Every interior face is split into 2 faces, 3 faces are added for each interior cell, and one in each hybrid cell */
370: depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, hybrid cells split into 2 cells */
371: break;
372: case REFINER_SIMPLEX_TO_HEX_2D:
373: depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
374: depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */
375: depthSize[2] = 3*(cEnd - cStart); /* Every cell split into 3 cells */
376: break;
377: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
378: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
379: depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
380: depthSize[1] = 2*(fEnd - fStart) + 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every face is split into 2 faces and 3 faces are added for each cell. 4 for each hybrid cell */
381: depthSize[2] = 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every cell split into 3 cells, hybrid cells split in 4 */
382: break;
383: case REFINER_HEX_2D:
384: depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
385: depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */
386: depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
387: break;
388: case REFINER_HYBRID_HEX_2D:
389: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
390: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
391: /* Quadrilateral */
392: depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */
393: depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */
394: depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */
395: /* Segment Prisms */
396: depthSize[0] += 0; /* No hybrid vertices */
397: depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */
398: depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */
399: break;
400: case REFINER_SIMPLEX_3D:
401: depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */
402: depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + (cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 1 edge for each cell */
403: depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */
404: depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */
405: break;
406: case REFINER_HYBRID_SIMPLEX_3D:
407: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
408: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
409: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
410: /* Tetrahedra */
411: depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */
412: depthSize[1] = 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 1 edge for each interior cell */
413: depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */
414: depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */
415: /* Triangular Prisms */
416: depthSize[0] += 0; /* No hybrid vertices */
417: depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */
418: depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */
419: depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */
420: break;
421: case REFINER_SIMPLEX_TO_HEX_3D:
422: depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */
423: depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + 4*(cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 4 for each cell */
424: depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */
425: depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
426: break;
427: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
428: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
429: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
430: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
431: /* Tetrahedra */
432: depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every interior edge, face and cell */
433: depthSize[1] = 2*(eMax - eStart) + 3*(fMax - fStart) + 4*(cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 4 edges for each interior cell */
434: depthSize[2] = 3*(fMax - fStart) + 6*(cMax - cStart); /* Every interior face split into 3 faces, 6 faces added for each interior cell */
435: depthSize[3] = 4*(cMax - cStart); /* Every interior cell split into 8 cells */
436: /* Triangular Prisms */
437: depthSize[0] += 0; /* No hybrid vertices */
438: depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and cell */
439: depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */
440: depthSize[3] += 3*(cEnd - cMax); /* Every hybrid cell split into 3 cells */
441: break;
442: case REFINER_HEX_3D:
443: depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
444: depthSize[1] = 2*(eEnd - eStart) + 4*(fEnd - fStart) + 6*(cEnd - cStart); /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */
445: depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */
446: depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */
447: break;
448: case REFINER_HYBRID_HEX_3D:
449: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
450: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
451: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
452: /* Hexahedra */
453: depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
454: depthSize[1] = 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart); /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */
455: depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */
456: depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */
457: /* Quadrilateral Prisms */
458: depthSize[0] += 0; /* No hybrid vertices */
459: depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
460: depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */
461: depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */
462: break;
463: default:
464: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
465: }
466: return(0);
467: }
469: /* Return triangle edge for orientation o, if it is r for o == 0 */
470: PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
471: return (o < 0 ? 2-(o+r) : o+r)%3;
472: }
473: PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
474: return (o < 0 ? 2-(o+s) : 3+s-o)%3;
475: }
477: /* Return triangle subface for orientation o, if it is r for o == 0 */
478: PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
479: return (o < 0 ? 3-(o+r) : o+r)%3;
480: }
481: PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
482: return (o < 0 ? 3-(o+s) : 3+s-o)%3;
483: }
485: /* Return the interior edge number connecting the midpoints of the triangle edges r
486: and r+1 in the transitive closure for triangle orientation o */
487: PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) {
488: return (o < 0 ? 1-(o+r) : o+r)%3;
489: }
490: PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) {
491: return (o < 0 ? 1-(o+s) : 3+s-o)%3;
492: }
494: /* Return the interior edge number connecting the midpoint of the triangle edge r
495: (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */
496: PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) {
497: return (o < 0 ? 2-(o+r) : o+r)%3;
498: }
499: PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) {
500: return (o < 0 ? 2-(o+s) : 3+s-o)%3;
501: }
503: /* Return quad edge for orientation o, if it is r for o == 0 */
504: PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
505: return (o < 0 ? 3-(o+r) : o+r)%4;
506: }
507: PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
508: return (o < 0 ? 3-(o+s) : 4+s-o)%4;
509: }
511: /* Return quad subface for orientation o, if it is r for o == 0 */
512: PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
513: return (o < 0 ? 4-(o+r) : o+r)%4;
514: }
515: PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
516: return (o < 0 ? 4-(o+s) : 4+s-o)%4;
517: }
519: static PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd)
520: {
521: IS cIS;
525: ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);
526: DMLabelSetStratumIS(label, value, cIS);
527: ISDestroy(&cIS);
528: return(0);
529: }
531: static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
532: {
533: PetscInt depth, cStart, cStartNew, cEnd, cEndNew, cMax, c, vStart, vStartNew, vEnd, vEndNew, vMax, v, fStart, fStartNew, fEnd, fEndNew, fMax, f, eStart, eStartNew, eEnd, eEndNew, eMax, e, r;
534: DMLabel depthLabel;
538: DMPlexGetDepth(dm, &depth);
539: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
540: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
541: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
542: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
543: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
544: GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);
545: GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);
546: DMCreateLabel(rdm,"depth");
547: DMPlexGetDepthLabel(rdm,&depthLabel);
548: DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);
549: if (depth > 2) DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);
550: if (depth > 1) DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);
551: if (depth > 0) DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);
552: {
553: DM_Plex *plex = (DM_Plex *) rdm->data;
554: PetscObjectStateGet((PetscObject) depthLabel, &plex->depthState);
555: }
556: if (!refiner) return(0);
557: switch (refiner) {
558: case REFINER_SIMPLEX_1D:
559: /* All cells have 2 vertices */
560: for (c = cStart; c < cEnd; ++c) {
561: for (r = 0; r < 2; ++r) {
562: const PetscInt newp = cStartNew + (c - cStart)*2 + r;
564: DMPlexSetConeSize(rdm, newp, 2);
565: }
566: }
567: /* Old vertices have identical supports */
568: for (v = vStart; v < vEnd; ++v) {
569: const PetscInt newp = vStartNew + (v - vStart);
570: PetscInt size;
572: DMPlexGetSupportSize(dm, v, &size);
573: DMPlexSetSupportSize(rdm, newp, size);
574: }
575: /* Cell vertices have support 2 */
576: for (c = cStart; c < cEnd; ++c) {
577: const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart);
579: DMPlexSetSupportSize(rdm, newp, 2);
580: }
581: break;
582: case REFINER_SIMPLEX_2D:
583: /* All cells have 3 faces */
584: for (c = cStart; c < cEnd; ++c) {
585: for (r = 0; r < 4; ++r) {
586: const PetscInt newp = (c - cStart)*4 + r;
588: DMPlexSetConeSize(rdm, newp, 3);
589: }
590: }
591: /* Split faces have 2 vertices and the same cells as the parent */
592: for (f = fStart; f < fEnd; ++f) {
593: for (r = 0; r < 2; ++r) {
594: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
595: PetscInt size;
597: DMPlexSetConeSize(rdm, newp, 2);
598: DMPlexGetSupportSize(dm, f, &size);
599: DMPlexSetSupportSize(rdm, newp, size);
600: }
601: }
602: /* Interior faces have 2 vertices and 2 cells */
603: for (c = cStart; c < cEnd; ++c) {
604: for (r = 0; r < 3; ++r) {
605: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
607: DMPlexSetConeSize(rdm, newp, 2);
608: DMPlexSetSupportSize(rdm, newp, 2);
609: }
610: }
611: /* Old vertices have identical supports */
612: for (v = vStart; v < vEnd; ++v) {
613: const PetscInt newp = vStartNew + (v - vStart);
614: PetscInt size;
616: DMPlexGetSupportSize(dm, v, &size);
617: DMPlexSetSupportSize(rdm, newp, size);
618: }
619: /* Face vertices have 2 + cells*2 supports */
620: for (f = fStart; f < fEnd; ++f) {
621: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
622: PetscInt size;
624: DMPlexGetSupportSize(dm, f, &size);
625: DMPlexSetSupportSize(rdm, newp, 2 + size*2);
626: }
627: break;
628: case REFINER_SIMPLEX_TO_HEX_2D:
629: /* All cells have 4 faces */
630: for (c = cStart; c < cEnd; ++c) {
631: for (r = 0; r < 3; ++r) {
632: const PetscInt newp = (c - cStart)*3 + r;
634: DMPlexSetConeSize(rdm, newp, 4);
635: }
636: }
637: /* Split faces have 2 vertices and the same cells as the parent */
638: for (f = fStart; f < fEnd; ++f) {
639: for (r = 0; r < 2; ++r) {
640: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
641: PetscInt size;
643: DMPlexSetConeSize(rdm, newp, 2);
644: DMPlexGetSupportSize(dm, f, &size);
645: DMPlexSetSupportSize(rdm, newp, size);
646: }
647: }
648: /* Interior faces have 2 vertices and 2 cells */
649: for (c = cStart; c < cEnd; ++c) {
650: for (r = 0; r < 3; ++r) {
651: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
653: DMPlexSetConeSize(rdm, newp, 2);
654: DMPlexSetSupportSize(rdm, newp, 2);
655: }
656: }
657: /* Old vertices have identical supports */
658: for (v = vStart; v < vEnd; ++v) {
659: const PetscInt newp = vStartNew + (v - vStart);
660: PetscInt size;
662: DMPlexGetSupportSize(dm, v, &size);
663: DMPlexSetSupportSize(rdm, newp, size);
664: }
665: /* Split-face vertices have cells + 2 supports */
666: for (f = fStart; f < fEnd; ++f) {
667: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
668: PetscInt size;
670: DMPlexGetSupportSize(dm, f, &size);
671: DMPlexSetSupportSize(rdm, newp, size + 2);
672: }
673: /* Interior vertices have 3 supports */
674: for (c = cStart; c < cEnd; ++c) {
675: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
677: DMPlexSetSupportSize(rdm, newp, 3);
678: }
679: break;
680: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
681: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
682: /* the mesh is no longer hybrid */
683: cMax = PetscMin(cEnd, cMax);
684: /* All cells have 4 faces */
685: for (c = cStart; c < cMax; ++c) {
686: for (r = 0; r < 3; ++r) {
687: const PetscInt newp = (c - cStart)*3 + r;
689: DMPlexSetConeSize(rdm, newp, 4);
690: }
691: }
692: for (c = cMax; c < cEnd; ++c) {
693: for (r = 0; r < 4; ++r) {
694: const PetscInt newp = (cMax - cStart)*3 + (c - cMax)*4 + r;
696: DMPlexSetConeSize(rdm, newp, 4);
697: }
698: }
699: /* Split faces have 2 vertices and the same cells as the parent */
700: for (f = fStart; f < fEnd; ++f) {
701: for (r = 0; r < 2; ++r) {
702: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
703: PetscInt size;
705: DMPlexSetConeSize(rdm, newp, 2);
706: DMPlexGetSupportSize(dm, f, &size);
707: DMPlexSetSupportSize(rdm, newp, size);
708: }
709: }
710: /* Interior faces have 2 vertices and 2 cells */
711: for (c = cStart; c < cMax; ++c) {
712: for (r = 0; r < 3; ++r) {
713: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
715: DMPlexSetConeSize(rdm, newp, 2);
716: DMPlexSetSupportSize(rdm, newp, 2);
717: }
718: }
719: /* Hybrid interior faces have 2 vertices and 2 cells */
720: for (c = cMax; c < cEnd; ++c) {
721: for (r = 0; r < 4; ++r) {
722: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r;
724: DMPlexSetConeSize(rdm, newp, 2);
725: DMPlexSetSupportSize(rdm, newp, 2);
726: }
727: }
728: /* Old vertices have identical supports */
729: for (v = vStart; v < vEnd; ++v) {
730: const PetscInt newp = vStartNew + (v - vStart);
731: PetscInt size;
733: DMPlexGetSupportSize(dm, v, &size);
734: DMPlexSetSupportSize(rdm, newp, size);
735: }
736: /* Split-face vertices have cells + 2 supports */
737: for (f = fStart; f < fEnd; ++f) {
738: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
739: PetscInt size;
741: DMPlexGetSupportSize(dm, f, &size);
742: DMPlexSetSupportSize(rdm, newp, size + 2);
743: }
744: /* Interior vertices have 3 supports */
745: for (c = cStart; c < cMax; ++c) {
746: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
748: DMPlexSetSupportSize(rdm, newp, 3);
749: }
750: /* Hybrid interior vertices have 4 supports */
751: for (c = cMax; c < cEnd; ++c) {
752: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
754: DMPlexSetSupportSize(rdm, newp, 4);
755: }
756: break;
757: case REFINER_HEX_2D:
758: /* All cells have 4 faces */
759: for (c = cStart; c < cEnd; ++c) {
760: for (r = 0; r < 4; ++r) {
761: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
763: DMPlexSetConeSize(rdm, newp, 4);
764: }
765: }
766: /* Split faces have 2 vertices and the same cells as the parent */
767: for (f = fStart; f < fEnd; ++f) {
768: for (r = 0; r < 2; ++r) {
769: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
770: PetscInt size;
772: DMPlexSetConeSize(rdm, newp, 2);
773: DMPlexGetSupportSize(dm, f, &size);
774: DMPlexSetSupportSize(rdm, newp, size);
775: }
776: }
777: /* Interior faces have 2 vertices and 2 cells */
778: for (c = cStart; c < cEnd; ++c) {
779: for (r = 0; r < 4; ++r) {
780: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
782: DMPlexSetConeSize(rdm, newp, 2);
783: DMPlexSetSupportSize(rdm, newp, 2);
784: }
785: }
786: /* Old vertices have identical supports */
787: for (v = vStart; v < vEnd; ++v) {
788: const PetscInt newp = vStartNew + (v - vStart);
789: PetscInt size;
791: DMPlexGetSupportSize(dm, v, &size);
792: DMPlexSetSupportSize(rdm, newp, size);
793: }
794: /* Face vertices have 2 + cells supports */
795: for (f = fStart; f < fEnd; ++f) {
796: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
797: PetscInt size;
799: DMPlexGetSupportSize(dm, f, &size);
800: DMPlexSetSupportSize(rdm, newp, 2 + size);
801: }
802: /* Cell vertices have 4 supports */
803: for (c = cStart; c < cEnd; ++c) {
804: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
806: DMPlexSetSupportSize(rdm, newp, 4);
807: }
808: break;
809: case REFINER_HYBRID_SIMPLEX_2D:
810: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
811: cMax = PetscMin(cEnd, cMax);
812: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
813: fMax = PetscMin(fEnd, fMax);
814: DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);
815: /* Interior cells have 3 faces */
816: for (c = cStart; c < cMax; ++c) {
817: for (r = 0; r < 4; ++r) {
818: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
820: DMPlexSetConeSize(rdm, newp, 3);
821: }
822: }
823: /* Hybrid cells have 4 faces */
824: for (c = cMax; c < cEnd; ++c) {
825: for (r = 0; r < 2; ++r) {
826: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
828: DMPlexSetConeSize(rdm, newp, 4);
829: }
830: }
831: /* Interior split faces have 2 vertices and the same cells as the parent */
832: for (f = fStart; f < fMax; ++f) {
833: for (r = 0; r < 2; ++r) {
834: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
835: PetscInt size;
837: DMPlexSetConeSize(rdm, newp, 2);
838: DMPlexGetSupportSize(dm, f, &size);
839: DMPlexSetSupportSize(rdm, newp, size);
840: }
841: }
842: /* Interior cell faces have 2 vertices and 2 cells */
843: for (c = cStart; c < cMax; ++c) {
844: for (r = 0; r < 3; ++r) {
845: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
847: DMPlexSetConeSize(rdm, newp, 2);
848: DMPlexSetSupportSize(rdm, newp, 2);
849: }
850: }
851: /* Hybrid faces have 2 vertices and the same cells */
852: for (f = fMax; f < fEnd; ++f) {
853: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
854: PetscInt size;
856: DMPlexSetConeSize(rdm, newp, 2);
857: DMPlexGetSupportSize(dm, f, &size);
858: DMPlexSetSupportSize(rdm, newp, size);
859: }
860: /* Hybrid cell faces have 2 vertices and 2 cells */
861: for (c = cMax; c < cEnd; ++c) {
862: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
864: DMPlexSetConeSize(rdm, newp, 2);
865: DMPlexSetSupportSize(rdm, newp, 2);
866: }
867: /* Old vertices have identical supports */
868: for (v = vStart; v < vEnd; ++v) {
869: const PetscInt newp = vStartNew + (v - vStart);
870: PetscInt size;
872: DMPlexGetSupportSize(dm, v, &size);
873: DMPlexSetSupportSize(rdm, newp, size);
874: }
875: /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
876: for (f = fStart; f < fMax; ++f) {
877: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
878: const PetscInt *support;
879: PetscInt size, newSize = 2, s;
881: DMPlexGetSupportSize(dm, f, &size);
882: DMPlexGetSupport(dm, f, &support);
883: for (s = 0; s < size; ++s) {
884: if (support[s] >= cMax) newSize += 1;
885: else newSize += 2;
886: }
887: DMPlexSetSupportSize(rdm, newp, newSize);
888: }
889: break;
890: case REFINER_HYBRID_HEX_2D:
891: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
892: cMax = PetscMin(cEnd, cMax);
893: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
894: fMax = PetscMin(fEnd, fMax);
895: DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);
896: /* Interior cells have 4 faces */
897: for (c = cStart; c < cMax; ++c) {
898: for (r = 0; r < 4; ++r) {
899: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
901: DMPlexSetConeSize(rdm, newp, 4);
902: }
903: }
904: /* Hybrid cells have 4 faces */
905: for (c = cMax; c < cEnd; ++c) {
906: for (r = 0; r < 2; ++r) {
907: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
909: DMPlexSetConeSize(rdm, newp, 4);
910: }
911: }
912: /* Interior split faces have 2 vertices and the same cells as the parent */
913: for (f = fStart; f < fMax; ++f) {
914: for (r = 0; r < 2; ++r) {
915: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
916: PetscInt size;
918: DMPlexSetConeSize(rdm, newp, 2);
919: DMPlexGetSupportSize(dm, f, &size);
920: DMPlexSetSupportSize(rdm, newp, size);
921: }
922: }
923: /* Interior cell faces have 2 vertices and 2 cells */
924: for (c = cStart; c < cMax; ++c) {
925: for (r = 0; r < 4; ++r) {
926: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
928: DMPlexSetConeSize(rdm, newp, 2);
929: DMPlexSetSupportSize(rdm, newp, 2);
930: }
931: }
932: /* Hybrid faces have 2 vertices and the same cells */
933: for (f = fMax; f < fEnd; ++f) {
934: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
935: PetscInt size;
937: DMPlexSetConeSize(rdm, newp, 2);
938: DMPlexGetSupportSize(dm, f, &size);
939: DMPlexSetSupportSize(rdm, newp, size);
940: }
941: /* Hybrid cell faces have 2 vertices and 2 cells */
942: for (c = cMax; c < cEnd; ++c) {
943: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
945: DMPlexSetConeSize(rdm, newp, 2);
946: DMPlexSetSupportSize(rdm, newp, 2);
947: }
948: /* Old vertices have identical supports */
949: for (v = vStart; v < vEnd; ++v) {
950: const PetscInt newp = vStartNew + (v - vStart);
951: PetscInt size;
953: DMPlexGetSupportSize(dm, v, &size);
954: DMPlexSetSupportSize(rdm, newp, size);
955: }
956: /* Face vertices have 2 + cells supports */
957: for (f = fStart; f < fMax; ++f) {
958: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
959: PetscInt size;
961: DMPlexGetSupportSize(dm, f, &size);
962: DMPlexSetSupportSize(rdm, newp, 2 + size);
963: }
964: /* Cell vertices have 4 supports */
965: for (c = cStart; c < cMax; ++c) {
966: const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
968: DMPlexSetSupportSize(rdm, newp, 4);
969: }
970: break;
971: case REFINER_SIMPLEX_3D:
972: /* All cells have 4 faces */
973: for (c = cStart; c < cEnd; ++c) {
974: for (r = 0; r < 8; ++r) {
975: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
977: DMPlexSetConeSize(rdm, newp, 4);
978: }
979: }
980: /* Split faces have 3 edges and the same cells as the parent */
981: for (f = fStart; f < fEnd; ++f) {
982: for (r = 0; r < 4; ++r) {
983: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
984: PetscInt size;
986: DMPlexSetConeSize(rdm, newp, 3);
987: DMPlexGetSupportSize(dm, f, &size);
988: DMPlexSetSupportSize(rdm, newp, size);
989: }
990: }
991: /* Interior cell faces have 3 edges and 2 cells */
992: for (c = cStart; c < cEnd; ++c) {
993: for (r = 0; r < 8; ++r) {
994: const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
996: DMPlexSetConeSize(rdm, newp, 3);
997: DMPlexSetSupportSize(rdm, newp, 2);
998: }
999: }
1000: /* Split edges have 2 vertices and the same faces */
1001: for (e = eStart; e < eEnd; ++e) {
1002: for (r = 0; r < 2; ++r) {
1003: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1004: PetscInt size;
1006: DMPlexSetConeSize(rdm, newp, 2);
1007: DMPlexGetSupportSize(dm, e, &size);
1008: DMPlexSetSupportSize(rdm, newp, size);
1009: }
1010: }
1011: /* Face edges have 2 vertices and 2+cells*(1/2) faces */
1012: for (f = fStart; f < fEnd; ++f) {
1013: for (r = 0; r < 3; ++r) {
1014: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
1015: const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
1016: PetscInt coneSize, c, supportSize, s, er, intFaces = 0;
1018: DMPlexSetConeSize(rdm, newp, 2);
1019: DMPlexGetSupportSize(dm, f, &supportSize);
1020: DMPlexGetSupport(dm, f, &support);
1021: for (s = 0; s < supportSize; ++s) {
1022: DMPlexGetConeSize(dm, support[s], &coneSize);
1023: DMPlexGetCone(dm, support[s], &cone);
1024: DMPlexGetConeOrientation(dm, support[s], &ornt);
1025: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
1026: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
1027: er = GetTriMidEdgeInverse_Static(ornt[c], r);
1028: if (er == eint[c]) {
1029: intFaces += 1;
1030: } else {
1031: intFaces += 2;
1032: }
1033: }
1034: DMPlexSetSupportSize(rdm, newp, 2+intFaces);
1035: }
1036: }
1037: /* Interior cell edges have 2 vertices and 4 faces */
1038: for (c = cStart; c < cEnd; ++c) {
1039: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
1041: DMPlexSetConeSize(rdm, newp, 2);
1042: DMPlexSetSupportSize(rdm, newp, 4);
1043: }
1044: /* Old vertices have identical supports */
1045: for (v = vStart; v < vEnd; ++v) {
1046: const PetscInt newp = vStartNew + (v - vStart);
1047: PetscInt size;
1049: DMPlexGetSupportSize(dm, v, &size);
1050: DMPlexSetSupportSize(rdm, newp, size);
1051: }
1052: /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
1053: for (e = eStart; e < eEnd; ++e) {
1054: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1055: PetscInt size, *star = NULL, starSize, s, cellSize = 0;
1057: DMPlexGetSupportSize(dm, e, &size);
1058: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
1059: for (s = 0; s < starSize*2; s += 2) {
1060: const PetscInt *cone, *ornt;
1061: PetscInt e01, e23;
1063: if ((star[s] >= cStart) && (star[s] < cEnd)) {
1064: /* Check edge 0-1 */
1065: DMPlexGetCone(dm, star[s], &cone);
1066: DMPlexGetConeOrientation(dm, star[s], &ornt);
1067: DMPlexGetCone(dm, cone[0], &cone);
1068: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
1069: /* Check edge 2-3 */
1070: DMPlexGetCone(dm, star[s], &cone);
1071: DMPlexGetConeOrientation(dm, star[s], &ornt);
1072: DMPlexGetCone(dm, cone[2], &cone);
1073: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
1074: if ((e01 == e) || (e23 == e)) ++cellSize;
1075: }
1076: }
1077: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
1078: DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);
1079: }
1080: break;
1081: case REFINER_HYBRID_SIMPLEX_3D:
1082: DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
1083: eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);
1084: /* Interior cells have 4 faces */
1085: for (c = cStart; c < cMax; ++c) {
1086: for (r = 0; r < 8; ++r) {
1087: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
1089: DMPlexSetConeSize(rdm, newp, 4);
1090: }
1091: }
1092: /* Hybrid cells have 5 faces */
1093: for (c = cMax; c < cEnd; ++c) {
1094: for (r = 0; r < 4; ++r) {
1095: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
1097: DMPlexSetConeSize(rdm, newp, 5);
1098: }
1099: }
1100: /* Interior split faces have 3 edges and the same cells as the parent */
1101: for (f = fStart; f < fMax; ++f) {
1102: for (r = 0; r < 4; ++r) {
1103: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
1104: PetscInt size;
1106: DMPlexSetConeSize(rdm, newp, 3);
1107: DMPlexGetSupportSize(dm, f, &size);
1108: DMPlexSetSupportSize(rdm, newp, size);
1109: }
1110: }
1111: /* Interior cell faces have 3 edges and 2 cells */
1112: for (c = cStart; c < cMax; ++c) {
1113: for (r = 0; r < 8; ++r) {
1114: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
1116: DMPlexSetConeSize(rdm, newp, 3);
1117: DMPlexSetSupportSize(rdm, newp, 2);
1118: }
1119: }
1120: /* Hybrid split faces have 4 edges and the same cells as the parent */
1121: for (f = fMax; f < fEnd; ++f) {
1122: for (r = 0; r < 2; ++r) {
1123: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
1124: PetscInt size;
1126: DMPlexSetConeSize(rdm, newp, 4);
1127: DMPlexGetSupportSize(dm, f, &size);
1128: DMPlexSetSupportSize(rdm, newp, size);
1129: }
1130: }
1131: /* Hybrid cells faces have 4 edges and 2 cells */
1132: for (c = cMax; c < cEnd; ++c) {
1133: for (r = 0; r < 3; ++r) {
1134: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
1136: DMPlexSetConeSize(rdm, newp, 4);
1137: DMPlexSetSupportSize(rdm, newp, 2);
1138: }
1139: }
1140: /* Interior split edges have 2 vertices and the same faces */
1141: for (e = eStart; e < eMax; ++e) {
1142: for (r = 0; r < 2; ++r) {
1143: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1144: PetscInt size;
1146: DMPlexSetConeSize(rdm, newp, 2);
1147: DMPlexGetSupportSize(dm, e, &size);
1148: DMPlexSetSupportSize(rdm, newp, size);
1149: }
1150: }
1151: /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
1152: for (f = fStart; f < fMax; ++f) {
1153: for (r = 0; r < 3; ++r) {
1154: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
1155: const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
1156: PetscInt coneSize, c, supportSize, s, er, intFaces = 0;
1158: DMPlexSetConeSize(rdm, newp, 2);
1159: DMPlexGetSupportSize(dm, f, &supportSize);
1160: DMPlexGetSupport(dm, f, &support);
1161: for (s = 0; s < supportSize; ++s) {
1162: DMPlexGetConeSize(dm, support[s], &coneSize);
1163: DMPlexGetCone(dm, support[s], &cone);
1164: DMPlexGetConeOrientation(dm, support[s], &ornt);
1165: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
1166: if (support[s] < cMax) {
1167: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
1168: er = GetTriMidEdgeInverse_Static(ornt[c], r);
1169: if (er == eint[c]) {
1170: intFaces += 1;
1171: } else {
1172: intFaces += 2;
1173: }
1174: } else {
1175: intFaces += 1;
1176: }
1177: }
1178: DMPlexSetSupportSize(rdm, newp, 2+intFaces);
1179: }
1180: }
1181: /* Interior cell edges have 2 vertices and 4 faces */
1182: for (c = cStart; c < cMax; ++c) {
1183: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
1185: DMPlexSetConeSize(rdm, newp, 2);
1186: DMPlexSetSupportSize(rdm, newp, 4);
1187: }
1188: /* Hybrid edges have 2 vertices and the same faces */
1189: for (e = eMax; e < eEnd; ++e) {
1190: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
1191: PetscInt size;
1193: DMPlexSetConeSize(rdm, newp, 2);
1194: DMPlexGetSupportSize(dm, e, &size);
1195: DMPlexSetSupportSize(rdm, newp, size);
1196: }
1197: /* Hybrid face edges have 2 vertices and 2+2*cells faces */
1198: for (f = fMax; f < fEnd; ++f) {
1199: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
1200: PetscInt size;
1202: DMPlexSetConeSize(rdm, newp, 2);
1203: DMPlexGetSupportSize(dm, f, &size);
1204: DMPlexSetSupportSize(rdm, newp, 2+2*size);
1205: }
1206: /* Interior vertices have identical supports */
1207: for (v = vStart; v < vEnd; ++v) {
1208: const PetscInt newp = vStartNew + (v - vStart);
1209: PetscInt size;
1211: DMPlexGetSupportSize(dm, v, &size);
1212: DMPlexSetSupportSize(rdm, newp, size);
1213: }
1214: /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
1215: for (e = eStart; e < eMax; ++e) {
1216: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1217: const PetscInt *support;
1218: PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
1220: DMPlexGetSupportSize(dm, e, &size);
1221: DMPlexGetSupport(dm, e, &support);
1222: for (s = 0; s < size; ++s) {
1223: if (support[s] < fMax) faceSize += 2;
1224: else faceSize += 1;
1225: }
1226: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
1227: for (s = 0; s < starSize*2; s += 2) {
1228: const PetscInt *cone, *ornt;
1229: PetscInt e01, e23;
1231: if ((star[s] >= cStart) && (star[s] < cMax)) {
1232: /* Check edge 0-1 */
1233: DMPlexGetCone(dm, star[s], &cone);
1234: DMPlexGetConeOrientation(dm, star[s], &ornt);
1235: DMPlexGetCone(dm, cone[0], &cone);
1236: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
1237: /* Check edge 2-3 */
1238: DMPlexGetCone(dm, star[s], &cone);
1239: DMPlexGetConeOrientation(dm, star[s], &ornt);
1240: DMPlexGetCone(dm, cone[2], &cone);
1241: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
1242: if ((e01 == e) || (e23 == e)) ++cellSize;
1243: }
1244: }
1245: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
1246: DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);
1247: }
1248: break;
1249: case REFINER_SIMPLEX_TO_HEX_3D:
1250: /* All cells have 6 faces */
1251: for (c = cStart; c < cEnd; ++c) {
1252: for (r = 0; r < 4; ++r) {
1253: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
1255: DMPlexSetConeSize(rdm, newp, 6);
1256: }
1257: }
1258: /* Split faces have 4 edges and the same cells as the parent */
1259: for (f = fStart; f < fEnd; ++f) {
1260: for (r = 0; r < 3; ++r) {
1261: const PetscInt newp = fStartNew + (f - fStart)*3 + r;
1262: PetscInt size;
1264: DMPlexSetConeSize(rdm, newp, 4);
1265: DMPlexGetSupportSize(dm, f, &size);
1266: DMPlexSetSupportSize(rdm, newp, size);
1267: }
1268: }
1269: /* Interior cell faces have 4 edges and 2 cells */
1270: for (c = cStart; c < cEnd; ++c) {
1271: for (r = 0; r < 6; ++r) {
1272: const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r;
1274: DMPlexSetConeSize(rdm, newp, 4);
1275: DMPlexSetSupportSize(rdm, newp, 2);
1276: }
1277: }
1278: /* Split edges have 2 vertices and the same faces */
1279: for (e = eStart; e < eEnd; ++e) {
1280: for (r = 0; r < 2; ++r) {
1281: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1282: PetscInt size;
1284: DMPlexSetConeSize(rdm, newp, 2);
1285: DMPlexGetSupportSize(dm, e, &size);
1286: DMPlexSetSupportSize(rdm, newp, size);
1287: }
1288: }
1289: /* Face edges have 2 vertices and 2 + cell faces supports */
1290: for (f = fStart; f < fEnd; ++f) {
1291: for (r = 0; r < 3; ++r) {
1292: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
1293: PetscInt size;
1295: DMPlexSetConeSize(rdm, newp, 2);
1296: DMPlexGetSupportSize(dm, f, &size);
1297: DMPlexSetSupportSize(rdm, newp, 2+size);
1298: }
1299: }
1300: /* Interior cell edges have 2 vertices and 3 faces */
1301: for (c = cStart; c < cEnd; ++c) {
1302: for (r = 0; r < 4; ++r) {
1303: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
1305: DMPlexSetConeSize(rdm, newp, 2);
1306: DMPlexSetSupportSize(rdm, newp, 3);
1307: }
1308: }
1309: /* Old vertices have identical supports */
1310: for (v = vStart; v < vEnd; ++v) {
1311: const PetscInt newp = vStartNew + (v - vStart);
1312: PetscInt size;
1314: DMPlexGetSupportSize(dm, v, &size);
1315: DMPlexSetSupportSize(rdm, newp, size);
1316: }
1317: /* Edge vertices have 2 + faces supports */
1318: for (e = eStart; e < eEnd; ++e) {
1319: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1320: PetscInt size;
1322: DMPlexGetSupportSize(dm, e, &size);
1323: DMPlexSetSupportSize(rdm, newp, 2 + size);
1324: }
1325: /* Face vertices have 3 + cells supports */
1326: for (f = fStart; f < fEnd; ++f) {
1327: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
1328: PetscInt size;
1330: DMPlexGetSupportSize(dm, f, &size);
1331: DMPlexSetSupportSize(rdm, newp, 3 + size);
1332: }
1333: /* Interior cell vertices have 4 supports */
1334: for (c = cStart; c < cEnd; ++c) {
1335: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart;
1337: DMPlexSetSupportSize(rdm, newp, 4);
1338: }
1339: break;
1340: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
1341: /* the mesh is no longer hybrid */
1342: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1343: cMax = PetscMin(cEnd, cMax);
1344: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
1345: fMax = PetscMin(fEnd, fMax);
1346: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
1347: eMax = PetscMin(eEnd, eMax);
1348: /* All cells have 6 faces */
1349: for (c = cStart; c < cMax; ++c) {
1350: for (r = 0; r < 4; ++r) {
1351: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
1353: DMPlexSetConeSize(rdm, newp, 6);
1354: }
1355: }
1356: for (c = cMax; c < cEnd; ++c) {
1357: for (r = 0; r < 3; ++r) {
1358: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + r;
1360: DMPlexSetConeSize(rdm, newp, 6);
1361: }
1362: }
1363: /* Interior split faces have 4 edges and the same cells as the parent */
1364: for (f = fStart; f < fMax; ++f) {
1365: for (r = 0; r < 3; ++r) {
1366: const PetscInt newp = fStartNew + (f - fStart)*3 + r;
1367: PetscInt size;
1369: DMPlexSetConeSize(rdm, newp, 4);
1370: DMPlexGetSupportSize(dm, f, &size);
1371: DMPlexSetSupportSize(rdm, newp, size);
1372: }
1373: }
1374: /* Interior cell faces have 4 edges and 2 cells */
1375: for (c = cStart; c < cMax; ++c) {
1376: for (r = 0; r < 6; ++r) {
1377: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + r;
1379: DMPlexSetConeSize(rdm, newp, 4);
1380: DMPlexSetSupportSize(rdm, newp, 2);
1381: }
1382: }
1383: /* Hybrid split faces have 4 edges and the same cells as the parent */
1384: for (f = fMax; f < fEnd; ++f) {
1385: for (r = 0; r < 2; ++r) {
1386: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2 + r;
1387: PetscInt size;
1389: DMPlexSetConeSize(rdm, newp, 4);
1390: DMPlexGetSupportSize(dm, f, &size);
1391: DMPlexSetSupportSize(rdm, newp, size);
1392: }
1393: }
1394: /* Hybrid cell faces have 4 edges and 2 cells */
1395: for (c = cMax; c < cEnd; ++c) {
1396: for (r = 0; r < 3; ++r) {
1397: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
1399: DMPlexSetConeSize(rdm, newp, 4);
1400: DMPlexSetSupportSize(rdm, newp, 2);
1401: }
1402: }
1403: /* Interior split edges have 2 vertices and the same faces */
1404: for (e = eStart; e < eMax; ++e) {
1405: for (r = 0; r < 2; ++r) {
1406: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1407: PetscInt size;
1409: DMPlexSetConeSize(rdm, newp, 2);
1410: DMPlexGetSupportSize(dm, e, &size);
1411: DMPlexSetSupportSize(rdm, newp, size);
1412: }
1413: }
1414: /* Interior face edges have 2 vertices and 2 + cell faces supports */
1415: for (f = fStart; f < fMax; ++f) {
1416: for (r = 0; r < 3; ++r) {
1417: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
1418: PetscInt size;
1420: DMPlexSetConeSize(rdm, newp, 2);
1421: DMPlexGetSupportSize(dm, f, &size);
1422: DMPlexSetSupportSize(rdm, newp, 2+size);
1423: }
1424: }
1425: /* Interior cell edges have 2 vertices and 3 faces */
1426: for (c = cStart; c < cMax; ++c) {
1427: for (r = 0; r < 4; ++r) {
1428: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r;
1430: DMPlexSetConeSize(rdm, newp, 2);
1431: DMPlexSetSupportSize(rdm, newp, 3);
1432: }
1433: }
1434: /* Hybrid edges have 2 vertices and the same faces */
1435: for (e = eMax; e < eEnd; ++e) {
1436: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax);
1437: PetscInt size;
1439: DMPlexSetConeSize(rdm, newp, 2);
1440: DMPlexGetSupportSize(dm, e, &size);
1441: DMPlexSetSupportSize(rdm, newp, size);
1442: }
1443: /* Hybrid face edges have 2 vertices and 2+cells faces */
1444: for (f = fMax; f < fEnd; ++f) {
1445: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax);
1446: PetscInt size;
1448: DMPlexSetConeSize(rdm, newp, 2);
1449: DMPlexGetSupportSize(dm, f, &size);
1450: DMPlexSetSupportSize(rdm, newp, 2+size);
1451: }
1452: /* Hybrid cell edges have 2 vertices and 3 faces */
1453: for (c = cMax; c < cEnd; ++c) {
1454: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
1456: DMPlexSetConeSize(rdm, newp, 2);
1457: DMPlexSetSupportSize(rdm, newp, 3);
1458: }
1459: /* Old vertices have identical supports */
1460: for (v = vStart; v < vEnd; ++v) {
1461: const PetscInt newp = vStartNew + (v - vStart);
1462: PetscInt size;
1464: DMPlexGetSupportSize(dm, v, &size);
1465: DMPlexSetSupportSize(rdm, newp, size);
1466: }
1467: /* Interior edge vertices have 2 + faces supports */
1468: for (e = eStart; e < eMax; ++e) {
1469: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1470: PetscInt size;
1472: DMPlexGetSupportSize(dm, e, &size);
1473: DMPlexSetSupportSize(rdm, newp, 2 + size);
1474: }
1475: /* Interior face vertices have 3 + cells supports */
1476: for (f = fStart; f < fMax; ++f) {
1477: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart;
1478: PetscInt size;
1480: DMPlexGetSupportSize(dm, f, &size);
1481: DMPlexSetSupportSize(rdm, newp, 3 + size);
1482: }
1483: /* Interior cell vertices have 4 supports */
1484: for (c = cStart; c < cMax; ++c) {
1485: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart;
1487: DMPlexSetSupportSize(rdm, newp, 4);
1488: }
1489: break;
1490: case REFINER_HEX_3D:
1491: /* All cells have 6 faces */
1492: for (c = cStart; c < cEnd; ++c) {
1493: for (r = 0; r < 8; ++r) {
1494: const PetscInt newp = (c - cStart)*8 + r;
1496: DMPlexSetConeSize(rdm, newp, 6);
1497: }
1498: }
1499: /* Split faces have 4 edges and the same cells as the parent */
1500: for (f = fStart; f < fEnd; ++f) {
1501: for (r = 0; r < 4; ++r) {
1502: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
1503: PetscInt size;
1505: DMPlexSetConeSize(rdm, newp, 4);
1506: DMPlexGetSupportSize(dm, f, &size);
1507: DMPlexSetSupportSize(rdm, newp, size);
1508: }
1509: }
1510: /* Interior faces have 4 edges and 2 cells */
1511: for (c = cStart; c < cEnd; ++c) {
1512: for (r = 0; r < 12; ++r) {
1513: const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
1515: DMPlexSetConeSize(rdm, newp, 4);
1516: DMPlexSetSupportSize(rdm, newp, 2);
1517: }
1518: }
1519: /* Split edges have 2 vertices and the same faces as the parent */
1520: for (e = eStart; e < eEnd; ++e) {
1521: for (r = 0; r < 2; ++r) {
1522: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1523: PetscInt size;
1525: DMPlexSetConeSize(rdm, newp, 2);
1526: DMPlexGetSupportSize(dm, e, &size);
1527: DMPlexSetSupportSize(rdm, newp, size);
1528: }
1529: }
1530: /* Face edges have 2 vertices and 2+cells faces */
1531: for (f = fStart; f < fEnd; ++f) {
1532: for (r = 0; r < 4; ++r) {
1533: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
1534: PetscInt size;
1536: DMPlexSetConeSize(rdm, newp, 2);
1537: DMPlexGetSupportSize(dm, f, &size);
1538: DMPlexSetSupportSize(rdm, newp, 2+size);
1539: }
1540: }
1541: /* Cell edges have 2 vertices and 4 faces */
1542: for (c = cStart; c < cEnd; ++c) {
1543: for (r = 0; r < 6; ++r) {
1544: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
1546: DMPlexSetConeSize(rdm, newp, 2);
1547: DMPlexSetSupportSize(rdm, newp, 4);
1548: }
1549: }
1550: /* Old vertices have identical supports */
1551: for (v = vStart; v < vEnd; ++v) {
1552: const PetscInt newp = vStartNew + (v - vStart);
1553: PetscInt size;
1555: DMPlexGetSupportSize(dm, v, &size);
1556: DMPlexSetSupportSize(rdm, newp, size);
1557: }
1558: /* Edge vertices have 2 + faces supports */
1559: for (e = eStart; e < eEnd; ++e) {
1560: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1561: PetscInt size;
1563: DMPlexGetSupportSize(dm, e, &size);
1564: DMPlexSetSupportSize(rdm, newp, 2 + size);
1565: }
1566: /* Face vertices have 4 + cells supports */
1567: for (f = fStart; f < fEnd; ++f) {
1568: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
1569: PetscInt size;
1571: DMPlexGetSupportSize(dm, f, &size);
1572: DMPlexSetSupportSize(rdm, newp, 4 + size);
1573: }
1574: /* Cell vertices have 6 supports */
1575: for (c = cStart; c < cEnd; ++c) {
1576: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
1578: DMPlexSetSupportSize(rdm, newp, 6);
1579: }
1580: break;
1581: case REFINER_HYBRID_HEX_3D:
1582: DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
1583: eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);
1584: /* Interior cells have 6 faces */
1585: for (c = cStart; c < cMax; ++c) {
1586: for (r = 0; r < 8; ++r) {
1587: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
1589: DMPlexSetConeSize(rdm, newp, 6);
1590: }
1591: }
1592: /* Hybrid cells have 6 faces */
1593: for (c = cMax; c < cEnd; ++c) {
1594: for (r = 0; r < 4; ++r) {
1595: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
1597: DMPlexSetConeSize(rdm, newp, 6);
1598: }
1599: }
1600: /* Interior split faces have 4 edges and the same cells as the parent */
1601: for (f = fStart; f < fMax; ++f) {
1602: for (r = 0; r < 4; ++r) {
1603: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
1604: PetscInt size;
1606: DMPlexSetConeSize(rdm, newp, 4);
1607: DMPlexGetSupportSize(dm, f, &size);
1608: DMPlexSetSupportSize(rdm, newp, size);
1609: }
1610: }
1611: /* Interior cell faces have 4 edges and 2 cells */
1612: for (c = cStart; c < cMax; ++c) {
1613: for (r = 0; r < 12; ++r) {
1614: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
1616: DMPlexSetConeSize(rdm, newp, 4);
1617: DMPlexSetSupportSize(rdm, newp, 2);
1618: }
1619: }
1620: /* Hybrid split faces have 4 edges and the same cells as the parent */
1621: for (f = fMax; f < fEnd; ++f) {
1622: for (r = 0; r < 2; ++r) {
1623: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
1624: PetscInt size;
1626: DMPlexSetConeSize(rdm, newp, 4);
1627: DMPlexGetSupportSize(dm, f, &size);
1628: DMPlexSetSupportSize(rdm, newp, size);
1629: }
1630: }
1631: /* Hybrid cells faces have 4 edges and 2 cells */
1632: for (c = cMax; c < cEnd; ++c) {
1633: for (r = 0; r < 4; ++r) {
1634: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
1636: DMPlexSetConeSize(rdm, newp, 4);
1637: DMPlexSetSupportSize(rdm, newp, 2);
1638: }
1639: }
1640: /* Interior split edges have 2 vertices and the same faces as the parent */
1641: for (e = eStart; e < eMax; ++e) {
1642: for (r = 0; r < 2; ++r) {
1643: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1644: PetscInt size;
1646: DMPlexSetConeSize(rdm, newp, 2);
1647: DMPlexGetSupportSize(dm, e, &size);
1648: DMPlexSetSupportSize(rdm, newp, size);
1649: }
1650: }
1651: /* Interior face edges have 2 vertices and 2+cells faces */
1652: for (f = fStart; f < fMax; ++f) {
1653: for (r = 0; r < 4; ++r) {
1654: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
1655: PetscInt size;
1657: DMPlexSetConeSize(rdm, newp, 2);
1658: DMPlexGetSupportSize(dm, f, &size);
1659: DMPlexSetSupportSize(rdm, newp, 2+size);
1660: }
1661: }
1662: /* Interior cell edges have 2 vertices and 4 faces */
1663: for (c = cStart; c < cMax; ++c) {
1664: for (r = 0; r < 6; ++r) {
1665: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
1667: DMPlexSetConeSize(rdm, newp, 2);
1668: DMPlexSetSupportSize(rdm, newp, 4);
1669: }
1670: }
1671: /* Hybrid edges have 2 vertices and the same faces */
1672: for (e = eMax; e < eEnd; ++e) {
1673: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
1674: PetscInt size;
1676: DMPlexSetConeSize(rdm, newp, 2);
1677: DMPlexGetSupportSize(dm, e, &size);
1678: DMPlexSetSupportSize(rdm, newp, size);
1679: }
1680: /* Hybrid face edges have 2 vertices and 2+cells faces */
1681: for (f = fMax; f < fEnd; ++f) {
1682: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
1683: PetscInt size;
1685: DMPlexSetConeSize(rdm, newp, 2);
1686: DMPlexGetSupportSize(dm, f, &size);
1687: DMPlexSetSupportSize(rdm, newp, 2+size);
1688: }
1689: /* Hybrid cell edges have 2 vertices and 4 faces */
1690: for (c = cMax; c < cEnd; ++c) {
1691: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
1693: DMPlexSetConeSize(rdm, newp, 2);
1694: DMPlexSetSupportSize(rdm, newp, 4);
1695: }
1696: /* Interior vertices have identical supports */
1697: for (v = vStart; v < vEnd; ++v) {
1698: const PetscInt newp = vStartNew + (v - vStart);
1699: PetscInt size;
1701: DMPlexGetSupportSize(dm, v, &size);
1702: DMPlexSetSupportSize(rdm, newp, size);
1703: }
1704: /* Interior edge vertices have 2 + faces supports */
1705: for (e = eStart; e < eMax; ++e) {
1706: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1707: PetscInt size;
1709: DMPlexGetSupportSize(dm, e, &size);
1710: DMPlexSetSupportSize(rdm, newp, 2 + size);
1711: }
1712: /* Interior face vertices have 4 + cells supports */
1713: for (f = fStart; f < fMax; ++f) {
1714: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
1715: PetscInt size;
1717: DMPlexGetSupportSize(dm, f, &size);
1718: DMPlexSetSupportSize(rdm, newp, 4 + size);
1719: }
1720: /* Interior cell vertices have 6 supports */
1721: for (c = cStart; c < cMax; ++c) {
1722: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
1724: DMPlexSetSupportSize(rdm, newp, 6);
1725: }
1726: break;
1727: default:
1728: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
1729: }
1730: return(0);
1731: }
1733: static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
1734: {
1735: const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
1736: PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
1737: PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
1738: PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r;
1739: #if defined(PETSC_USE_DEBUG)
1740: PetscInt p;
1741: #endif
1742: PetscErrorCode ierr;
1745: if (!refiner) return(0);
1746: DMPlexGetDepth(dm, &depth);
1747: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
1748: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
1749: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
1750: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
1751: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
1752: GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);
1753: GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);
1754: switch (refiner) {
1755: case REFINER_SIMPLEX_1D:
1756: /* Max support size of refined mesh is 2 */
1757: PetscMalloc1(2, &supportRef);
1758: /* All cells have 2 vertices */
1759: for (c = cStart; c < cEnd; ++c) {
1760: const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart);
1762: for (r = 0; r < 2; ++r) {
1763: const PetscInt newp = cStartNew + (c - cStart)*2 + r;
1764: const PetscInt *cone;
1765: PetscInt coneNew[2];
1767: DMPlexGetCone(dm, c, &cone);
1768: coneNew[0] = vStartNew + (cone[0] - vStart);
1769: coneNew[1] = vStartNew + (cone[1] - vStart);
1770: coneNew[(r+1)%2] = newv;
1771: DMPlexSetCone(rdm, newp, coneNew);
1772: #if defined(PETSC_USE_DEBUG)
1773: if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp, cStartNew, cEndNew);
1774: for (p = 0; p < 2; ++p) {
1775: 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);
1776: }
1777: #endif
1778: }
1779: }
1780: /* Old vertices have identical supports */
1781: for (v = vStart; v < vEnd; ++v) {
1782: const PetscInt newp = vStartNew + (v - vStart);
1783: const PetscInt *support, *cone;
1784: PetscInt size, s;
1786: DMPlexGetSupportSize(dm, v, &size);
1787: DMPlexGetSupport(dm, v, &support);
1788: for (s = 0; s < size; ++s) {
1789: PetscInt r = 0;
1791: DMPlexGetCone(dm, support[s], &cone);
1792: if (cone[1] == v) r = 1;
1793: supportRef[s] = cStartNew + (support[s] - cStart)*2 + r;
1794: }
1795: DMPlexSetSupport(rdm, newp, supportRef);
1796: #if defined(PETSC_USE_DEBUG)
1797: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
1798: for (p = 0; p < size; ++p) {
1799: 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);
1800: }
1801: #endif
1802: }
1803: /* Cell vertices have support of 2 cells */
1804: for (c = cStart; c < cEnd; ++c) {
1805: const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart);
1807: supportRef[0] = cStartNew + (c - cStart)*2 + 0;
1808: supportRef[1] = cStartNew + (c - cStart)*2 + 1;
1809: DMPlexSetSupport(rdm, newp, supportRef);
1810: #if defined(PETSC_USE_DEBUG)
1811: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
1812: for (p = 0; p < 2; ++p) {
1813: 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);
1814: }
1815: #endif
1816: }
1817: PetscFree(supportRef);
1818: break;
1819: case REFINER_SIMPLEX_2D:
1820: /*
1821: 2
1822: |\
1823: | \
1824: | \
1825: | \
1826: | C \
1827: | \
1828: | \
1829: 2---1---1
1830: |\ D / \
1831: | 2 0 \
1832: |A \ / B \
1833: 0---0-------1
1834: */
1835: /* All cells have 3 faces */
1836: for (c = cStart; c < cEnd; ++c) {
1837: const PetscInt newp = cStartNew + (c - cStart)*4;
1838: const PetscInt *cone, *ornt;
1839: PetscInt coneNew[3], orntNew[3];
1841: DMPlexGetCone(dm, c, &cone);
1842: DMPlexGetConeOrientation(dm, c, &ornt);
1843: /* A triangle */
1844: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1845: orntNew[0] = ornt[0];
1846: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1847: orntNew[1] = -2;
1848: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1849: orntNew[2] = ornt[2];
1850: DMPlexSetCone(rdm, newp+0, coneNew);
1851: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
1852: #if defined(PETSC_USE_DEBUG)
1853: 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);
1854: for (p = 0; p < 3; ++p) {
1855: 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);
1856: }
1857: #endif
1858: /* B triangle */
1859: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1860: orntNew[0] = ornt[0];
1861: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1862: orntNew[1] = ornt[1];
1863: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1864: orntNew[2] = -2;
1865: DMPlexSetCone(rdm, newp+1, coneNew);
1866: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
1867: #if defined(PETSC_USE_DEBUG)
1868: 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);
1869: for (p = 0; p < 3; ++p) {
1870: 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);
1871: }
1872: #endif
1873: /* C triangle */
1874: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1875: orntNew[0] = -2;
1876: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1877: orntNew[1] = ornt[1];
1878: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1879: orntNew[2] = ornt[2];
1880: DMPlexSetCone(rdm, newp+2, coneNew);
1881: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
1882: #if defined(PETSC_USE_DEBUG)
1883: 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);
1884: for (p = 0; p < 3; ++p) {
1885: 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);
1886: }
1887: #endif
1888: /* D triangle */
1889: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1890: orntNew[0] = 0;
1891: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1892: orntNew[1] = 0;
1893: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1894: orntNew[2] = 0;
1895: DMPlexSetCone(rdm, newp+3, coneNew);
1896: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
1897: #if defined(PETSC_USE_DEBUG)
1898: 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);
1899: for (p = 0; p < 3; ++p) {
1900: 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);
1901: }
1902: #endif
1903: }
1904: /* Split faces have 2 vertices and the same cells as the parent */
1905: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
1906: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
1907: for (f = fStart; f < fEnd; ++f) {
1908: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1910: for (r = 0; r < 2; ++r) {
1911: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
1912: const PetscInt *cone, *ornt, *support;
1913: PetscInt coneNew[2], coneSize, c, supportSize, s;
1915: DMPlexGetCone(dm, f, &cone);
1916: coneNew[0] = vStartNew + (cone[0] - vStart);
1917: coneNew[1] = vStartNew + (cone[1] - vStart);
1918: coneNew[(r+1)%2] = newv;
1919: DMPlexSetCone(rdm, newp, coneNew);
1920: #if defined(PETSC_USE_DEBUG)
1921: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1922: for (p = 0; p < 2; ++p) {
1923: 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);
1924: }
1925: #endif
1926: DMPlexGetSupportSize(dm, f, &supportSize);
1927: DMPlexGetSupport(dm, f, &support);
1928: for (s = 0; s < supportSize; ++s) {
1929: DMPlexGetConeSize(dm, support[s], &coneSize);
1930: DMPlexGetCone(dm, support[s], &cone);
1931: DMPlexGetConeOrientation(dm, support[s], &ornt);
1932: for (c = 0; c < coneSize; ++c) {
1933: if (cone[c] == f) break;
1934: }
1935: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
1936: }
1937: DMPlexSetSupport(rdm, newp, supportRef);
1938: #if defined(PETSC_USE_DEBUG)
1939: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1940: for (p = 0; p < supportSize; ++p) {
1941: 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);
1942: }
1943: #endif
1944: }
1945: }
1946: /* Interior faces have 2 vertices and 2 cells */
1947: for (c = cStart; c < cEnd; ++c) {
1948: const PetscInt *cone;
1950: DMPlexGetCone(dm, c, &cone);
1951: for (r = 0; r < 3; ++r) {
1952: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
1953: PetscInt coneNew[2];
1954: PetscInt supportNew[2];
1956: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1957: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
1958: DMPlexSetCone(rdm, newp, coneNew);
1959: #if defined(PETSC_USE_DEBUG)
1960: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1961: for (p = 0; p < 2; ++p) {
1962: 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);
1963: }
1964: #endif
1965: supportNew[0] = (c - cStart)*4 + (r+1)%3;
1966: supportNew[1] = (c - cStart)*4 + 3;
1967: DMPlexSetSupport(rdm, newp, supportNew);
1968: #if defined(PETSC_USE_DEBUG)
1969: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
1970: for (p = 0; p < 2; ++p) {
1971: if ((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);
1972: }
1973: #endif
1974: }
1975: }
1976: /* Old vertices have identical supports */
1977: for (v = vStart; v < vEnd; ++v) {
1978: const PetscInt newp = vStartNew + (v - vStart);
1979: const PetscInt *support, *cone;
1980: PetscInt size, s;
1982: DMPlexGetSupportSize(dm, v, &size);
1983: DMPlexGetSupport(dm, v, &support);
1984: for (s = 0; s < size; ++s) {
1985: PetscInt r = 0;
1987: DMPlexGetCone(dm, support[s], &cone);
1988: if (cone[1] == v) r = 1;
1989: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
1990: }
1991: DMPlexSetSupport(rdm, newp, supportRef);
1992: #if defined(PETSC_USE_DEBUG)
1993: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
1994: for (p = 0; p < size; ++p) {
1995: 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);
1996: }
1997: #endif
1998: }
1999: /* Face vertices have 2 + cells*2 supports */
2000: for (f = fStart; f < fEnd; ++f) {
2001: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2002: const PetscInt *cone, *support;
2003: PetscInt size, s;
2005: DMPlexGetSupportSize(dm, f, &size);
2006: DMPlexGetSupport(dm, f, &support);
2007: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2008: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2009: for (s = 0; s < size; ++s) {
2010: PetscInt r = 0;
2012: DMPlexGetCone(dm, support[s], &cone);
2013: if (cone[1] == f) r = 1;
2014: else if (cone[2] == f) r = 2;
2015: supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
2016: supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
2017: }
2018: DMPlexSetSupport(rdm, newp, supportRef);
2019: #if defined(PETSC_USE_DEBUG)
2020: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2021: for (p = 0; p < 2+size*2; ++p) {
2022: 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);
2023: }
2024: #endif
2025: }
2026: PetscFree(supportRef);
2027: break;
2028: case REFINER_SIMPLEX_TO_HEX_2D:
2029: /*
2030: 2
2031: |\
2032: | \
2033: | \
2034: | \
2035: | C \
2036: | \
2037: 2 1
2038: |\ / \
2039: | 2 1 \
2040: | \/ \
2041: | | \
2042: |A | B \
2043: | 0 \
2044: | | \
2045: 0---0----------1
2046: */
2047: /* All cells have 4 faces */
2048: for (c = cStart; c < cEnd; ++c) {
2049: const PetscInt newp = cStartNew + (c - cStart)*3;
2050: const PetscInt *cone, *ornt;
2051: PetscInt coneNew[4], orntNew[4];
2053: DMPlexGetCone(dm, c, &cone);
2054: DMPlexGetConeOrientation(dm, c, &ornt);
2055: /* A quad */
2056: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2057: orntNew[0] = ornt[0];
2058: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2059: orntNew[1] = 0;
2060: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2061: orntNew[2] = -2;
2062: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2063: orntNew[3] = ornt[2];
2064: DMPlexSetCone(rdm, newp+0, coneNew);
2065: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2066: #if defined(PETSC_USE_DEBUG)
2067: 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);
2068: for (p = 0; p < 4; ++p) {
2069: 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);
2070: }
2071: #endif
2072: /* B quad */
2073: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2074: orntNew[0] = ornt[0];
2075: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2076: orntNew[1] = ornt[1];
2077: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2078: orntNew[2] = 0;
2079: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2080: orntNew[3] = -2;
2081: DMPlexSetCone(rdm, newp+1, coneNew);
2082: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2083: #if defined(PETSC_USE_DEBUG)
2084: 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);
2085: for (p = 0; p < 4; ++p) {
2086: 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);
2087: }
2088: #endif
2089: /* C quad */
2090: coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2091: orntNew[0] = ornt[1];
2092: coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2093: orntNew[1] = ornt[2];
2094: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2095: orntNew[2] = 0;
2096: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2097: orntNew[3] = -2;
2098: DMPlexSetCone(rdm, newp+2, coneNew);
2099: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2100: #if defined(PETSC_USE_DEBUG)
2101: 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);
2102: for (p = 0; p < 4; ++p) {
2103: 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);
2104: }
2105: #endif
2106: }
2107: /* Split faces have 2 vertices and the same cells as the parent */
2108: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2109: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2110: for (f = fStart; f < fEnd; ++f) {
2111: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2113: for (r = 0; r < 2; ++r) {
2114: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2115: const PetscInt *cone, *ornt, *support;
2116: PetscInt coneNew[2], coneSize, c, supportSize, s;
2118: DMPlexGetCone(dm, f, &cone);
2119: coneNew[0] = vStartNew + (cone[0] - vStart);
2120: coneNew[1] = vStartNew + (cone[1] - vStart);
2121: coneNew[(r+1)%2] = newv;
2122: DMPlexSetCone(rdm, newp, coneNew);
2123: #if defined(PETSC_USE_DEBUG)
2124: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2125: for (p = 0; p < 2; ++p) {
2126: 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);
2127: }
2128: #endif
2129: DMPlexGetSupportSize(dm, f, &supportSize);
2130: DMPlexGetSupport(dm, f, &support);
2131: for (s = 0; s < supportSize; ++s) {
2132: DMPlexGetConeSize(dm, support[s], &coneSize);
2133: DMPlexGetCone(dm, support[s], &cone);
2134: DMPlexGetConeOrientation(dm, support[s], &ornt);
2135: for (c = 0; c < coneSize; ++c) {
2136: if (cone[c] == f) break;
2137: }
2138: supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
2139: }
2140: DMPlexSetSupport(rdm, newp, supportRef);
2141: #if defined(PETSC_USE_DEBUG)
2142: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2143: for (p = 0; p < supportSize; ++p) {
2144: 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);
2145: }
2146: #endif
2147: }
2148: }
2149: /* Interior faces have 2 vertices and 2 cells */
2150: for (c = cStart; c < cEnd; ++c) {
2151: const PetscInt *cone;
2153: DMPlexGetCone(dm, c, &cone);
2154: for (r = 0; r < 3; ++r) {
2155: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
2156: PetscInt coneNew[2];
2157: PetscInt supportNew[2];
2159: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2160: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2161: DMPlexSetCone(rdm, newp, coneNew);
2162: #if defined(PETSC_USE_DEBUG)
2163: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2164: for (p = 0; p < 2; ++p) {
2165: 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);
2166: }
2167: #endif
2168: supportNew[0] = (c - cStart)*3 + r%3;
2169: supportNew[1] = (c - cStart)*3 + (r+1)%3;
2170: DMPlexSetSupport(rdm, newp, supportNew);
2171: #if defined(PETSC_USE_DEBUG)
2172: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2173: for (p = 0; p < 2; ++p) {
2174: if ((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);
2175: }
2176: #endif
2177: }
2178: }
2179: /* Old vertices have identical supports */
2180: for (v = vStart; v < vEnd; ++v) {
2181: const PetscInt newp = vStartNew + (v - vStart);
2182: const PetscInt *support, *cone;
2183: PetscInt size, s;
2185: DMPlexGetSupportSize(dm, v, &size);
2186: DMPlexGetSupport(dm, v, &support);
2187: for (s = 0; s < size; ++s) {
2188: PetscInt r = 0;
2190: DMPlexGetCone(dm, support[s], &cone);
2191: if (cone[1] == v) r = 1;
2192: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2193: }
2194: DMPlexSetSupport(rdm, newp, supportRef);
2195: #if defined(PETSC_USE_DEBUG)
2196: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2197: for (p = 0; p < size; ++p) {
2198: 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);
2199: }
2200: #endif
2201: }
2202: /* Split-face vertices have cells + 2 supports */
2203: for (f = fStart; f < fEnd; ++f) {
2204: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2205: const PetscInt *cone, *support;
2206: PetscInt size, s;
2208: DMPlexGetSupportSize(dm, f, &size);
2209: DMPlexGetSupport(dm, f, &support);
2210: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2211: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2212: for (s = 0; s < size; ++s) {
2213: PetscInt r = 0;
2215: DMPlexGetCone(dm, support[s], &cone);
2216: if (cone[1] == f) r = 1;
2217: else if (cone[2] == f) r = 2;
2218: supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
2219: }
2220: DMPlexSetSupport(rdm, newp, supportRef);
2221: #if defined(PETSC_USE_DEBUG)
2222: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2223: for (p = 0; p < 2+size; ++p) {
2224: 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);
2225: }
2226: #endif
2227: }
2228: /* Interior vertices have 3 supports */
2229: for (c = cStart; c < cEnd; ++c) {
2230: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
2232: supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2233: supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2234: supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2235: DMPlexSetSupport(rdm, newp, supportRef);
2236: }
2237: PetscFree(supportRef);
2238: break;
2239: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
2240: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2241: cMax = PetscMin(cEnd, cMax);
2242: for (c = cStart; c < cMax; ++c) {
2243: const PetscInt newp = cStartNew + (c - cStart)*3;
2244: const PetscInt *cone, *ornt;
2245: PetscInt coneNew[4], orntNew[4];
2247: DMPlexGetCone(dm, c, &cone);
2248: DMPlexGetConeOrientation(dm, c, &ornt);
2249: /* A quad */
2250: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2251: orntNew[0] = ornt[0];
2252: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2253: orntNew[1] = 0;
2254: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2255: orntNew[2] = -2;
2256: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2257: orntNew[3] = ornt[2];
2258: DMPlexSetCone(rdm, newp+0, coneNew);
2259: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2260: #if defined(PETSC_USE_DEBUG)
2261: 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);
2262: for (p = 0; p < 4; ++p) {
2263: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew);
2264: }
2265: #endif
2266: /* B quad */
2267: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2268: orntNew[0] = ornt[0];
2269: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2270: orntNew[1] = ornt[1];
2271: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2272: orntNew[2] = 0;
2273: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2274: orntNew[3] = -2;
2275: DMPlexSetCone(rdm, newp+1, coneNew);
2276: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2277: #if defined(PETSC_USE_DEBUG)
2278: 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);
2279: for (p = 0; p < 4; ++p) {
2280: 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);
2281: }
2282: #endif
2283: /* C quad */
2284: coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2285: orntNew[0] = ornt[1];
2286: coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2287: orntNew[1] = ornt[2];
2288: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2289: orntNew[2] = 0;
2290: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2291: orntNew[3] = -2;
2292: DMPlexSetCone(rdm, newp+2, coneNew);
2293: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2294: #if defined(PETSC_USE_DEBUG)
2295: 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);
2296: for (p = 0; p < 4; ++p) {
2297: 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);
2298: }
2299: #endif
2300: }
2301: /*
2302: 2---------1---------3
2303: | | |
2304: | D 1 C |
2305: | | |
2306: 2----2----0----3----3
2307: | | |
2308: | A 0 B |
2309: | | |
2310: 0---------0---------1
2311: */
2312: /* Parent cells are input as prisms but children are quads, since the mesh is no longer hybrid */
2313: for (c = cMax; c < cEnd; ++c) {
2314: const PetscInt newp = cStartNew + (cMax - cStart)*3 + (c - cMax)*4;
2315: const PetscInt newpt = (cMax - cStart)*3 + (c - cMax)*4;
2316: const PetscInt *cone, *ornt;
2317: PetscInt coneNew[4], orntNew[4];
2319: DMPlexGetCone(dm, c, &cone);
2320: DMPlexGetConeOrientation(dm, c, &ornt);
2321: /* A quad */
2322: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2323: orntNew[0] = ornt[0];
2324: coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 0;
2325: orntNew[1] = 0;
2326: coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 2;
2327: orntNew[2] = -2;
2328: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2329: orntNew[3] = ornt[2] < 0 ? 0 : -2;
2330: DMPlexSetCone(rdm, newp+0, coneNew);
2331: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2332: #if defined(PETSC_USE_DEBUG)
2333: 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);
2334: for (p = 0; p < 4; ++p) {
2335: 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);
2336: }
2337: #endif
2338: /* B quad */
2339: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2340: orntNew[0] = ornt[0];
2341: coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2342: orntNew[1] = ornt[3];
2343: coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 3;
2344: orntNew[2] = 0;
2345: coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 0;
2346: orntNew[3] = -2;
2347: DMPlexSetCone(rdm, newp+1, coneNew);
2348: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2349: #if defined(PETSC_USE_DEBUG)
2350: 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);
2351: for (p = 0; p < 4; ++p) {
2352: 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);
2353: }
2354: #endif
2355: /* C quad */
2356: coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 3;
2357: orntNew[0] = -2;
2358: coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
2359: orntNew[1] = ornt[3];
2360: coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2361: orntNew[2] = ornt[1] < 0 ? 0 : -2;
2362: coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 1;
2363: orntNew[3] = 0;
2364: DMPlexSetCone(rdm, newp+2, coneNew);
2365: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2366: #if defined(PETSC_USE_DEBUG)
2367: 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);
2368: for (p = 0; p < 4; ++p) {
2369: 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);
2370: }
2371: #endif
2372: /* D quad */
2373: coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 2;
2374: orntNew[0] = 0;
2375: coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 1;
2376: orntNew[1] = -2;
2377: coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2378: orntNew[2] = ornt[1] < 0 ? 0 : -2;
2379: coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2380: orntNew[3] = ornt[2] < 0 ? 0 : -2;
2381: DMPlexSetCone(rdm, newp+3, coneNew);
2382: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2383: #if defined(PETSC_USE_DEBUG)
2384: 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);
2385: for (p = 0; p < 4; ++p) {
2386: 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);
2387: }
2388: #endif
2389: }
2390: /* Split faces have 2 vertices and the same cells as the parent */
2391: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2392: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2393: for (f = fStart; f < fEnd; ++f) {
2394: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2396: for (r = 0; r < 2; ++r) {
2397: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2398: const PetscInt *cone, *ornt, *support;
2399: PetscInt coneNew[2], coneSize, c, supportSize, s;
2401: DMPlexGetCone(dm, f, &cone);
2402: coneNew[0] = vStartNew + (cone[0] - vStart);
2403: coneNew[1] = vStartNew + (cone[1] - vStart);
2404: coneNew[(r+1)%2] = newv;
2405: DMPlexSetCone(rdm, newp, coneNew);
2406: #if defined(PETSC_USE_DEBUG)
2407: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2408: for (p = 0; p < 2; ++p) {
2409: 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);
2410: }
2411: #endif
2412: DMPlexGetSupportSize(dm, f, &supportSize);
2413: DMPlexGetSupport(dm, f, &support);
2414: for (s = 0; s < supportSize; ++s) {
2415: const PetscInt p2q[4][2] = { {0, 1},
2416: {3, 2},
2417: {0, 3},
2418: {1, 2} };
2420: DMPlexGetConeSize(dm, support[s], &coneSize);
2421: DMPlexGetCone(dm, support[s], &cone);
2422: DMPlexGetConeOrientation(dm, support[s], &ornt);
2423: for (c = 0; c < coneSize; ++c) {
2424: if (cone[c] == f) break;
2425: }
2426: if (coneSize == 3) supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
2427: 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]);
2428: else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize);
2429: }
2430: DMPlexSetSupport(rdm, newp, supportRef);
2431: #if defined(PETSC_USE_DEBUG)
2432: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2433: for (p = 0; p < supportSize; ++p) {
2434: 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);
2435: }
2436: #endif
2437: }
2438: }
2439: /* Interior faces have 2 vertices and 2 cells */
2440: for (c = cStart; c < cMax; ++c) {
2441: const PetscInt *cone;
2443: DMPlexGetCone(dm, c, &cone);
2444: for (r = 0; r < 3; ++r) {
2445: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
2446: PetscInt coneNew[2];
2447: PetscInt supportNew[2];
2449: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2450: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2451: DMPlexSetCone(rdm, newp, coneNew);
2452: #if defined(PETSC_USE_DEBUG)
2453: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2454: for (p = 0; p < 2; ++p) {
2455: 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);
2456: }
2457: #endif
2458: supportNew[0] = (c - cStart)*3 + r%3;
2459: supportNew[1] = (c - cStart)*3 + (r+1)%3;
2460: DMPlexSetSupport(rdm, newp, supportNew);
2461: #if defined(PETSC_USE_DEBUG)
2462: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2463: for (p = 0; p < 2; ++p) {
2464: if ((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);
2465: }
2466: #endif
2467: }
2468: }
2469: /* Hybrid interior faces have 2 vertices and 2 cells */
2470: for (c = cMax; c < cEnd; ++c) {
2471: const PetscInt *cone;
2472: PetscInt coneNew[2], supportNew[2];
2474: DMPlexGetCone(dm, c, &cone);
2475: for (r = 0; r < 4; ++r) {
2476: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r;
2478: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2479: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (cMax - cStart) + (c - cMax);
2480: DMPlexSetCone(rdm, newp, coneNew);
2481: #if defined(PETSC_USE_DEBUG)
2482: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2483: for (p = 0; p < 2; ++p) {
2484: 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);
2485: }
2486: #endif
2487: if (r==0) {
2488: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0;
2489: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 1;
2490: } else if (r==1) {
2491: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 2;
2492: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3;
2493: } else if (r==2) {
2494: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0;
2495: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3;
2496: } else {
2497: supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 1;
2498: supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 2;
2499: }
2500: DMPlexSetSupport(rdm, newp, supportNew);
2501: #if defined(PETSC_USE_DEBUG)
2502: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2503: for (p = 0; p < 2; ++p) {
2504: 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);
2505: }
2506: #endif
2507: }
2508: }
2509: /* Old vertices have identical supports */
2510: for (v = vStart; v < vEnd; ++v) {
2511: const PetscInt newp = vStartNew + (v - vStart);
2512: const PetscInt *support, *cone;
2513: PetscInt size, s;
2515: DMPlexGetSupportSize(dm, v, &size);
2516: DMPlexGetSupport(dm, v, &support);
2517: for (s = 0; s < size; ++s) {
2518: PetscInt r = 0;
2520: DMPlexGetCone(dm, support[s], &cone);
2521: if (cone[1] == v) r = 1;
2522: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2523: }
2524: DMPlexSetSupport(rdm, newp, supportRef);
2525: #if defined(PETSC_USE_DEBUG)
2526: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2527: for (p = 0; p < size; ++p) {
2528: 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);
2529: }
2530: #endif
2531: }
2532: /* Split-face vertices have cells + 2 supports */
2533: for (f = fStart; f < fEnd; ++f) {
2534: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2535: const PetscInt *cone, *support;
2536: PetscInt size, s;
2538: DMPlexGetSupportSize(dm, f, &size);
2539: DMPlexGetSupport(dm, f, &support);
2540: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2541: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2542: for (s = 0; s < size; ++s) {
2543: PetscInt r = 0, coneSize;
2545: DMPlexGetCone(dm, support[s], &cone);
2546: DMPlexGetConeSize(dm, support[s], &coneSize);
2547: if (coneSize == 3) {
2548: if (cone[1] == f) r = 1;
2549: else if (cone[2] == f) r = 2;
2550: supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
2551: } else if (coneSize == 4) {
2552: if (cone[1] == f) r = 1;
2553: else if (cone[2] == f) r = 2;
2554: else if (cone[3] == f) r = 3;
2555: supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (support[s] - cMax)*4 + r;
2556: } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize);
2557: }
2558: DMPlexSetSupport(rdm, newp, supportRef);
2559: #if defined(PETSC_USE_DEBUG)
2560: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2561: for (p = 0; p < 2+size; ++p) {
2562: 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);
2563: }
2564: #endif
2565: }
2566: /* Interior vertices have 3 supports */
2567: for (c = cStart; c < cMax; ++c) {
2568: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
2570: supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
2571: supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
2572: supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
2573: DMPlexSetSupport(rdm, newp, supportRef);
2574: }
2575: /* Hybrid interior vertices have 4 supports */
2576: for (c = cMax; c < cEnd; ++c) {
2577: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
2579: supportRef[0] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 0;
2580: supportRef[1] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 1;
2581: supportRef[2] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 2;
2582: supportRef[3] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 3;
2583: DMPlexSetSupport(rdm, newp, supportRef);
2584: }
2585: PetscFree(supportRef);
2586: break;
2587: case REFINER_HEX_2D:
2588: /*
2589: 3---------2---------2
2590: | | |
2591: | D 2 C |
2592: | | |
2593: 3----3----0----1----1
2594: | | |
2595: | A 0 B |
2596: | | |
2597: 0---------0---------1
2598: */
2599: /* All cells have 4 faces */
2600: for (c = cStart; c < cEnd; ++c) {
2601: const PetscInt newp = (c - cStart)*4;
2602: const PetscInt *cone, *ornt;
2603: PetscInt coneNew[4], orntNew[4];
2605: DMPlexGetCone(dm, c, &cone);
2606: DMPlexGetConeOrientation(dm, c, &ornt);
2607: /* A quad */
2608: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2609: orntNew[0] = ornt[0];
2610: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0;
2611: orntNew[1] = 0;
2612: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3;
2613: orntNew[2] = -2;
2614: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
2615: orntNew[3] = ornt[3];
2616: DMPlexSetCone(rdm, newp+0, coneNew);
2617: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2618: #if defined(PETSC_USE_DEBUG)
2619: 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);
2620: for (p = 0; p < 4; ++p) {
2621: 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);
2622: }
2623: #endif
2624: /* B quad */
2625: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2626: orntNew[0] = ornt[0];
2627: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2628: orntNew[1] = ornt[1];
2629: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1;
2630: orntNew[2] = -2;
2631: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0;
2632: orntNew[3] = -2;
2633: DMPlexSetCone(rdm, newp+1, coneNew);
2634: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2635: #if defined(PETSC_USE_DEBUG)
2636: 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);
2637: for (p = 0; p < 4; ++p) {
2638: 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);
2639: }
2640: #endif
2641: /* C quad */
2642: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1;
2643: orntNew[0] = 0;
2644: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2645: orntNew[1] = ornt[1];
2646: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2647: orntNew[2] = ornt[2];
2648: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2;
2649: orntNew[3] = -2;
2650: DMPlexSetCone(rdm, newp+2, coneNew);
2651: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2652: #if defined(PETSC_USE_DEBUG)
2653: 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);
2654: for (p = 0; p < 4; ++p) {
2655: 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);
2656: }
2657: #endif
2658: /* D quad */
2659: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3;
2660: orntNew[0] = 0;
2661: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2;
2662: orntNew[1] = 0;
2663: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2664: orntNew[2] = ornt[2];
2665: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2666: orntNew[3] = ornt[3];
2667: DMPlexSetCone(rdm, newp+3, coneNew);
2668: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2669: #if defined(PETSC_USE_DEBUG)
2670: 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);
2671: for (p = 0; p < 4; ++p) {
2672: 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);
2673: }
2674: #endif
2675: }
2676: /* Split faces have 2 vertices and the same cells as the parent */
2677: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2678: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2679: for (f = fStart; f < fEnd; ++f) {
2680: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2682: for (r = 0; r < 2; ++r) {
2683: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2684: const PetscInt *cone, *ornt, *support;
2685: PetscInt coneNew[2], coneSize, c, supportSize, s;
2687: DMPlexGetCone(dm, f, &cone);
2688: coneNew[0] = vStartNew + (cone[0] - vStart);
2689: coneNew[1] = vStartNew + (cone[1] - vStart);
2690: coneNew[(r+1)%2] = newv;
2691: DMPlexSetCone(rdm, newp, coneNew);
2692: #if defined(PETSC_USE_DEBUG)
2693: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2694: for (p = 0; p < 2; ++p) {
2695: 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);
2696: }
2697: #endif
2698: DMPlexGetSupportSize(dm, f, &supportSize);
2699: DMPlexGetSupport(dm, f, &support);
2700: for (s = 0; s < supportSize; ++s) {
2701: DMPlexGetConeSize(dm, support[s], &coneSize);
2702: DMPlexGetCone(dm, support[s], &cone);
2703: DMPlexGetConeOrientation(dm, support[s], &ornt);
2704: for (c = 0; c < coneSize; ++c) {
2705: if (cone[c] == f) break;
2706: }
2707: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2708: }
2709: DMPlexSetSupport(rdm, newp, supportRef);
2710: #if defined(PETSC_USE_DEBUG)
2711: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2712: for (p = 0; p < supportSize; ++p) {
2713: 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);
2714: }
2715: #endif
2716: }
2717: }
2718: /* Interior faces have 2 vertices and 2 cells */
2719: for (c = cStart; c < cEnd; ++c) {
2720: const PetscInt *cone;
2721: PetscInt coneNew[2], supportNew[2];
2723: DMPlexGetCone(dm, c, &cone);
2724: for (r = 0; r < 4; ++r) {
2725: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
2727: if (r==1 || r==2) {
2728: coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2729: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2730: } else {
2731: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2732: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2733: }
2734: DMPlexSetCone(rdm, newp, coneNew);
2735: #if defined(PETSC_USE_DEBUG)
2736: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2737: for (p = 0; p < 2; ++p) {
2738: 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);
2739: }
2740: #endif
2741: supportNew[0] = (c - cStart)*4 + r;
2742: supportNew[1] = (c - cStart)*4 + (r+1)%4;
2743: DMPlexSetSupport(rdm, newp, supportNew);
2744: #if defined(PETSC_USE_DEBUG)
2745: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2746: for (p = 0; p < 2; ++p) {
2747: if ((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);
2748: }
2749: #endif
2750: }
2751: }
2752: /* Old vertices have identical supports */
2753: for (v = vStart; v < vEnd; ++v) {
2754: const PetscInt newp = vStartNew + (v - vStart);
2755: const PetscInt *support, *cone;
2756: PetscInt size, s;
2758: DMPlexGetSupportSize(dm, v, &size);
2759: DMPlexGetSupport(dm, v, &support);
2760: for (s = 0; s < size; ++s) {
2761: PetscInt r = 0;
2763: DMPlexGetCone(dm, support[s], &cone);
2764: if (cone[1] == v) r = 1;
2765: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2766: }
2767: DMPlexSetSupport(rdm, newp, supportRef);
2768: #if defined(PETSC_USE_DEBUG)
2769: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2770: for (p = 0; p < size; ++p) {
2771: 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);
2772: }
2773: #endif
2774: }
2775: /* Face vertices have 2 + cells supports */
2776: for (f = fStart; f < fEnd; ++f) {
2777: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
2778: const PetscInt *cone, *support;
2779: PetscInt size, s;
2781: DMPlexGetSupportSize(dm, f, &size);
2782: DMPlexGetSupport(dm, f, &support);
2783: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2784: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2785: for (s = 0; s < size; ++s) {
2786: PetscInt r = 0;
2788: DMPlexGetCone(dm, support[s], &cone);
2789: if (cone[1] == f) r = 1;
2790: else if (cone[2] == f) r = 2;
2791: else if (cone[3] == f) r = 3;
2792: supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
2793: }
2794: DMPlexSetSupport(rdm, newp, supportRef);
2795: #if defined(PETSC_USE_DEBUG)
2796: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
2797: for (p = 0; p < 2+size; ++p) {
2798: 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);
2799: }
2800: #endif
2801: }
2802: /* Cell vertices have 4 supports */
2803: for (c = cStart; c < cEnd; ++c) {
2804: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
2805: PetscInt supportNew[4];
2807: for (r = 0; r < 4; ++r) {
2808: supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
2809: }
2810: DMPlexSetSupport(rdm, newp, supportNew);
2811: }
2812: PetscFree(supportRef);
2813: break;
2814: case REFINER_HYBRID_SIMPLEX_2D:
2815: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2816: cMax = PetscMin(cEnd, cMax);
2817: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
2818: fMax = PetscMin(fEnd, fMax);
2819: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);
2820: /* Interior cells have 3 faces */
2821: for (c = cStart; c < cMax; ++c) {
2822: const PetscInt newp = cStartNew + (c - cStart)*4;
2823: const PetscInt *cone, *ornt;
2824: PetscInt coneNew[3], orntNew[3];
2826: DMPlexGetCone(dm, c, &cone);
2827: DMPlexGetConeOrientation(dm, c, &ornt);
2828: /* A triangle */
2829: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2830: orntNew[0] = ornt[0];
2831: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2;
2832: orntNew[1] = -2;
2833: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2834: orntNew[2] = ornt[2];
2835: DMPlexSetCone(rdm, newp+0, coneNew);
2836: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2837: #if defined(PETSC_USE_DEBUG)
2838: 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);
2839: for (p = 0; p < 3; ++p) {
2840: 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);
2841: }
2842: #endif
2843: /* B triangle */
2844: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2845: orntNew[0] = ornt[0];
2846: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2847: orntNew[1] = ornt[1];
2848: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0;
2849: orntNew[2] = -2;
2850: DMPlexSetCone(rdm, newp+1, coneNew);
2851: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2852: #if defined(PETSC_USE_DEBUG)
2853: 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);
2854: for (p = 0; p < 3; ++p) {
2855: 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);
2856: }
2857: #endif
2858: /* C triangle */
2859: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1;
2860: orntNew[0] = -2;
2861: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2862: orntNew[1] = ornt[1];
2863: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2864: orntNew[2] = ornt[2];
2865: DMPlexSetCone(rdm, newp+2, coneNew);
2866: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2867: #if defined(PETSC_USE_DEBUG)
2868: 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);
2869: for (p = 0; p < 3; ++p) {
2870: 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);
2871: }
2872: #endif
2873: /* D triangle */
2874: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0;
2875: orntNew[0] = 0;
2876: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1;
2877: orntNew[1] = 0;
2878: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2;
2879: orntNew[2] = 0;
2880: DMPlexSetCone(rdm, newp+3, coneNew);
2881: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2882: #if defined(PETSC_USE_DEBUG)
2883: 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);
2884: for (p = 0; p < 3; ++p) {
2885: 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);
2886: }
2887: #endif
2888: }
2889: /*
2890: 2----3----3
2891: | |
2892: | B |
2893: | |
2894: 0----4--- 1
2895: | |
2896: | A |
2897: | |
2898: 0----2----1
2899: */
2900: /* Hybrid cells have 4 faces */
2901: for (c = cMax; c < cEnd; ++c) {
2902: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
2903: const PetscInt *cone, *ornt;
2904: PetscInt coneNew[4], orntNew[4], r;
2906: DMPlexGetCone(dm, c, &cone);
2907: DMPlexGetConeOrientation(dm, c, &ornt);
2908: r = (ornt[0] < 0 ? 1 : 0);
2909: /* A quad */
2910: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r;
2911: orntNew[0] = ornt[0];
2912: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r;
2913: orntNew[1] = ornt[1];
2914: coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
2915: orntNew[2+r] = 0;
2916: coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
2917: orntNew[3-r] = 0;
2918: DMPlexSetCone(rdm, newp+0, coneNew);
2919: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2920: #if defined(PETSC_USE_DEBUG)
2921: 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);
2922: for (p = 0; p < 4; ++p) {
2923: 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);
2924: }
2925: #endif
2926: /* B quad */
2927: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r;
2928: orntNew[0] = ornt[0];
2929: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r;
2930: orntNew[1] = ornt[1];
2931: coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
2932: orntNew[2+r] = 0;
2933: coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
2934: orntNew[3-r] = 0;
2935: DMPlexSetCone(rdm, newp+1, coneNew);
2936: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2937: #if defined(PETSC_USE_DEBUG)
2938: 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);
2939: for (p = 0; p < 4; ++p) {
2940: 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);
2941: }
2942: #endif
2943: }
2944: /* Interior split faces have 2 vertices and the same cells as the parent */
2945: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2946: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
2947: for (f = fStart; f < fMax; ++f) {
2948: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2950: for (r = 0; r < 2; ++r) {
2951: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
2952: const PetscInt *cone, *ornt, *support;
2953: PetscInt coneNew[2], coneSize, c, supportSize, s;
2955: DMPlexGetCone(dm, f, &cone);
2956: coneNew[0] = vStartNew + (cone[0] - vStart);
2957: coneNew[1] = vStartNew + (cone[1] - vStart);
2958: coneNew[(r+1)%2] = newv;
2959: DMPlexSetCone(rdm, newp, coneNew);
2960: #if defined(PETSC_USE_DEBUG)
2961: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2962: for (p = 0; p < 2; ++p) {
2963: 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);
2964: }
2965: #endif
2966: DMPlexGetSupportSize(dm, f, &supportSize);
2967: DMPlexGetSupport(dm, f, &support);
2968: for (s = 0; s < supportSize; ++s) {
2969: DMPlexGetConeSize(dm, support[s], &coneSize);
2970: DMPlexGetCone(dm, support[s], &cone);
2971: DMPlexGetConeOrientation(dm, support[s], &ornt);
2972: for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
2973: if (support[s] >= cMax) {
2974: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
2975: } else {
2976: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
2977: }
2978: }
2979: DMPlexSetSupport(rdm, newp, supportRef);
2980: #if defined(PETSC_USE_DEBUG)
2981: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
2982: for (p = 0; p < supportSize; ++p) {
2983: 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);
2984: }
2985: #endif
2986: }
2987: }
2988: /* Interior cell faces have 2 vertices and 2 cells */
2989: for (c = cStart; c < cMax; ++c) {
2990: const PetscInt *cone;
2992: DMPlexGetCone(dm, c, &cone);
2993: for (r = 0; r < 3; ++r) {
2994: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
2995: PetscInt coneNew[2];
2996: PetscInt supportNew[2];
2998: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2999: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
3000: DMPlexSetCone(rdm, newp, coneNew);
3001: #if defined(PETSC_USE_DEBUG)
3002: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3003: for (p = 0; p < 2; ++p) {
3004: 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);
3005: }
3006: #endif
3007: supportNew[0] = (c - cStart)*4 + (r+1)%3;
3008: supportNew[1] = (c - cStart)*4 + 3;
3009: DMPlexSetSupport(rdm, newp, supportNew);
3010: #if defined(PETSC_USE_DEBUG)
3011: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3012: for (p = 0; p < 2; ++p) {
3013: if ((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);
3014: }
3015: #endif
3016: }
3017: }
3018: /* Interior hybrid faces have 2 vertices and the same cells */
3019: for (f = fMax; f < fEnd; ++f) {
3020: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
3021: const PetscInt *cone, *ornt;
3022: const PetscInt *support;
3023: PetscInt coneNew[2];
3024: PetscInt supportNew[2];
3025: PetscInt size, s, r;
3027: DMPlexGetCone(dm, f, &cone);
3028: coneNew[0] = vStartNew + (cone[0] - vStart);
3029: coneNew[1] = vStartNew + (cone[1] - vStart);
3030: DMPlexSetCone(rdm, newp, coneNew);
3031: #if defined(PETSC_USE_DEBUG)
3032: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3033: for (p = 0; p < 2; ++p) {
3034: 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);
3035: }
3036: #endif
3037: DMPlexGetSupportSize(dm, f, &size);
3038: DMPlexGetSupport(dm, f, &support);
3039: for (s = 0; s < size; ++s) {
3040: DMPlexGetCone(dm, support[s], &cone);
3041: DMPlexGetConeOrientation(dm, support[s], &ornt);
3042: for (r = 0; r < 2; ++r) {
3043: if (cone[r+2] == f) break;
3044: }
3045: supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
3046: }
3047: DMPlexSetSupport(rdm, newp, supportNew);
3048: #if defined(PETSC_USE_DEBUG)
3049: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3050: for (p = 0; p < size; ++p) {
3051: 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);
3052: }
3053: #endif
3054: }
3055: /* Cell hybrid faces have 2 vertices and 2 cells */
3056: for (c = cMax; c < cEnd; ++c) {
3057: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
3058: const PetscInt *cone;
3059: PetscInt coneNew[2];
3060: PetscInt supportNew[2];
3062: DMPlexGetCone(dm, c, &cone);
3063: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
3064: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
3065: DMPlexSetCone(rdm, newp, coneNew);
3066: #if defined(PETSC_USE_DEBUG)
3067: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3068: for (p = 0; p < 2; ++p) {
3069: 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);
3070: }
3071: #endif
3072: supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
3073: supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
3074: DMPlexSetSupport(rdm, newp, supportNew);
3075: #if defined(PETSC_USE_DEBUG)
3076: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3077: for (p = 0; p < 2; ++p) {
3078: if ((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);
3079: }
3080: #endif
3081: }
3082: /* Old vertices have identical supports */
3083: for (v = vStart; v < vEnd; ++v) {
3084: const PetscInt newp = vStartNew + (v - vStart);
3085: const PetscInt *support, *cone;
3086: PetscInt size, s;
3088: DMPlexGetSupportSize(dm, v, &size);
3089: DMPlexGetSupport(dm, v, &support);
3090: for (s = 0; s < size; ++s) {
3091: if (support[s] >= fMax) {
3092: supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
3093: } else {
3094: PetscInt r = 0;
3096: DMPlexGetCone(dm, support[s], &cone);
3097: if (cone[1] == v) r = 1;
3098: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
3099: }
3100: }
3101: DMPlexSetSupport(rdm, newp, supportRef);
3102: #if defined(PETSC_USE_DEBUG)
3103: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3104: for (p = 0; p < size; ++p) {
3105: 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);
3106: }
3107: #endif
3108: }
3109: /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
3110: for (f = fStart; f < fMax; ++f) {
3111: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
3112: const PetscInt *cone, *support;
3113: PetscInt size, newSize = 2, s;
3115: DMPlexGetSupportSize(dm, f, &size);
3116: DMPlexGetSupport(dm, f, &support);
3117: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
3118: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
3119: for (s = 0; s < size; ++s) {
3120: PetscInt r = 0;
3122: DMPlexGetCone(dm, support[s], &cone);
3123: if (support[s] >= cMax) {
3124: supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
3126: newSize += 1;
3127: } else {
3128: if (cone[1] == f) r = 1;
3129: else if (cone[2] == f) r = 2;
3130: supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
3131: supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
3133: newSize += 2;
3134: }
3135: }
3136: DMPlexSetSupport(rdm, newp, supportRef);
3137: #if defined(PETSC_USE_DEBUG)
3138: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3139: for (p = 0; p < newSize; ++p) {
3140: 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);
3141: }
3142: #endif
3143: }
3144: PetscFree(supportRef);
3145: break;
3146: case REFINER_HYBRID_HEX_2D:
3147: /* Hybrid Hex 2D */
3148: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
3149: cMax = PetscMin(cEnd, cMax);
3150: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
3151: fMax = PetscMin(fEnd, fMax);
3152: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);
3153: /* Interior cells have 4 faces */
3154: for (c = cStart; c < cMax; ++c) {
3155: const PetscInt newp = cStartNew + (c - cStart)*4;
3156: const PetscInt *cone, *ornt;
3157: PetscInt coneNew[4], orntNew[4];
3159: DMPlexGetCone(dm, c, &cone);
3160: DMPlexGetConeOrientation(dm, c, &ornt);
3161: /* A quad */
3162: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
3163: orntNew[0] = ornt[0];
3164: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0;
3165: orntNew[1] = 0;
3166: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3;
3167: orntNew[2] = -2;
3168: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
3169: orntNew[3] = ornt[3];
3170: DMPlexSetCone(rdm, newp+0, coneNew);
3171: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3172: #if defined(PETSC_USE_DEBUG)
3173: 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);
3174: for (p = 0; p < 4; ++p) {
3175: 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);
3176: }
3177: #endif
3178: /* B quad */
3179: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
3180: orntNew[0] = ornt[0];
3181: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
3182: orntNew[1] = ornt[1];
3183: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1;
3184: orntNew[2] = 0;
3185: coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0;
3186: orntNew[3] = -2;
3187: DMPlexSetCone(rdm, newp+1, coneNew);
3188: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3189: #if defined(PETSC_USE_DEBUG)
3190: 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);
3191: for (p = 0; p < 4; ++p) {
3192: 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);
3193: }
3194: #endif
3195: /* C quad */
3196: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1;
3197: orntNew[0] = -2;
3198: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
3199: orntNew[1] = ornt[1];
3200: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
3201: orntNew[2] = ornt[2];
3202: coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2;
3203: orntNew[3] = 0;
3204: DMPlexSetCone(rdm, newp+2, coneNew);
3205: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3206: #if defined(PETSC_USE_DEBUG)
3207: 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);
3208: for (p = 0; p < 4; ++p) {
3209: 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);
3210: }
3211: #endif
3212: /* D quad */
3213: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3;
3214: orntNew[0] = 0;
3215: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2;
3216: orntNew[1] = -2;
3217: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
3218: orntNew[2] = ornt[2];
3219: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
3220: orntNew[3] = ornt[3];
3221: DMPlexSetCone(rdm, newp+3, coneNew);
3222: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3223: #if defined(PETSC_USE_DEBUG)
3224: 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);
3225: for (p = 0; p < 4; ++p) {
3226: 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);
3227: }
3228: #endif
3229: }
3230: /*
3231: 2----3----3
3232: | |
3233: | B |
3234: | |
3235: 0----4--- 1
3236: | |
3237: | A |
3238: | |
3239: 0----2----1
3240: */
3241: /* Hybrid cells have 4 faces */
3242: for (c = cMax; c < cEnd; ++c) {
3243: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
3244: const PetscInt *cone, *ornt;
3245: PetscInt coneNew[4], orntNew[4];
3247: DMPlexGetCone(dm, c, &cone);
3248: DMPlexGetConeOrientation(dm, c, &ornt);
3249: /* A quad */
3250: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
3251: orntNew[0] = ornt[0];
3252: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
3253: orntNew[1] = ornt[1];
3254: coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
3255: orntNew[2] = 0;
3256: coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
3257: orntNew[3] = 0;
3258: DMPlexSetCone(rdm, newp+0, coneNew);
3259: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3260: #if defined(PETSC_USE_DEBUG)
3261: 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);
3262: for (p = 0; p < 4; ++p) {
3263: 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);
3264: }
3265: #endif
3266: /* B quad */
3267: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
3268: orntNew[0] = ornt[0];
3269: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
3270: orntNew[1] = ornt[1];
3271: coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
3272: orntNew[2] = 0;
3273: coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
3274: orntNew[3] = 0;
3275: DMPlexSetCone(rdm, newp+1, coneNew);
3276: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3277: #if defined(PETSC_USE_DEBUG)
3278: 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);
3279: for (p = 0; p < 4; ++p) {
3280: 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);
3281: }
3282: #endif
3283: }
3284: /* Interior split faces have 2 vertices and the same cells as the parent */
3285: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
3286: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
3287: for (f = fStart; f < fMax; ++f) {
3288: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
3290: for (r = 0; r < 2; ++r) {
3291: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
3292: const PetscInt *cone, *ornt, *support;
3293: PetscInt coneNew[2], coneSize, c, supportSize, s;
3295: DMPlexGetCone(dm, f, &cone);
3296: coneNew[0] = vStartNew + (cone[0] - vStart);
3297: coneNew[1] = vStartNew + (cone[1] - vStart);
3298: coneNew[(r+1)%2] = newv;
3299: DMPlexSetCone(rdm, newp, coneNew);
3300: #if defined(PETSC_USE_DEBUG)
3301: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3302: for (p = 0; p < 2; ++p) {
3303: 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);
3304: }
3305: #endif
3306: DMPlexGetSupportSize(dm, f, &supportSize);
3307: DMPlexGetSupport(dm, f, &support);
3308: for (s = 0; s < supportSize; ++s) {
3309: if (support[s] >= cMax) {
3310: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
3311: } else {
3312: DMPlexGetConeSize(dm, support[s], &coneSize);
3313: DMPlexGetCone(dm, support[s], &cone);
3314: DMPlexGetConeOrientation(dm, support[s], &ornt);
3315: for (c = 0; c < coneSize; ++c) {
3316: if (cone[c] == f) break;
3317: }
3318: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
3319: }
3320: }
3321: DMPlexSetSupport(rdm, newp, supportRef);
3322: #if defined(PETSC_USE_DEBUG)
3323: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3324: for (p = 0; p < supportSize; ++p) {
3325: 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);
3326: }
3327: #endif
3328: }
3329: }
3330: /* Interior cell faces have 2 vertices and 2 cells */
3331: for (c = cStart; c < cMax; ++c) {
3332: const PetscInt *cone;
3334: DMPlexGetCone(dm, c, &cone);
3335: for (r = 0; r < 4; ++r) {
3336: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
3337: PetscInt coneNew[2], supportNew[2];
3339: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
3340: coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
3341: DMPlexSetCone(rdm, newp, coneNew);
3342: #if defined(PETSC_USE_DEBUG)
3343: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3344: for (p = 0; p < 2; ++p) {
3345: 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);
3346: }
3347: #endif
3348: supportNew[0] = (c - cStart)*4 + r;
3349: supportNew[1] = (c - cStart)*4 + (r+1)%4;
3350: DMPlexSetSupport(rdm, newp, supportNew);
3351: #if defined(PETSC_USE_DEBUG)
3352: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3353: for (p = 0; p < 2; ++p) {
3354: if ((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);
3355: }
3356: #endif
3357: }
3358: }
3359: /* Hybrid faces have 2 vertices and the same cells */
3360: for (f = fMax; f < fEnd; ++f) {
3361: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
3362: const PetscInt *cone, *support;
3363: PetscInt coneNew[2], supportNew[2];
3364: PetscInt size, s, r;
3366: DMPlexGetCone(dm, f, &cone);
3367: coneNew[0] = vStartNew + (cone[0] - vStart);
3368: coneNew[1] = vStartNew + (cone[1] - vStart);
3369: DMPlexSetCone(rdm, newp, coneNew);
3370: #if defined(PETSC_USE_DEBUG)
3371: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3372: for (p = 0; p < 2; ++p) {
3373: 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);
3374: }
3375: #endif
3376: DMPlexGetSupportSize(dm, f, &size);
3377: DMPlexGetSupport(dm, f, &support);
3378: for (s = 0; s < size; ++s) {
3379: DMPlexGetCone(dm, support[s], &cone);
3380: for (r = 0; r < 2; ++r) {
3381: if (cone[r+2] == f) break;
3382: }
3383: supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
3384: }
3385: DMPlexSetSupport(rdm, newp, supportNew);
3386: #if defined(PETSC_USE_DEBUG)
3387: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3388: for (p = 0; p < size; ++p) {
3389: 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);
3390: }
3391: #endif
3392: }
3393: /* Cell hybrid faces have 2 vertices and 2 cells */
3394: for (c = cMax; c < cEnd; ++c) {
3395: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
3396: const PetscInt *cone;
3397: PetscInt coneNew[2], supportNew[2];
3399: DMPlexGetCone(dm, c, &cone);
3400: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
3401: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
3402: DMPlexSetCone(rdm, newp, coneNew);
3403: #if defined(PETSC_USE_DEBUG)
3404: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3405: for (p = 0; p < 2; ++p) {
3406: 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);
3407: }
3408: #endif
3409: supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
3410: supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
3411: DMPlexSetSupport(rdm, newp, supportNew);
3412: #if defined(PETSC_USE_DEBUG)
3413: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3414: for (p = 0; p < 2; ++p) {
3415: if ((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);
3416: }
3417: #endif
3418: }
3419: /* Old vertices have identical supports */
3420: for (v = vStart; v < vEnd; ++v) {
3421: const PetscInt newp = vStartNew + (v - vStart);
3422: const PetscInt *support, *cone;
3423: PetscInt size, s;
3425: DMPlexGetSupportSize(dm, v, &size);
3426: DMPlexGetSupport(dm, v, &support);
3427: for (s = 0; s < size; ++s) {
3428: if (support[s] >= fMax) {
3429: supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
3430: } else {
3431: PetscInt r = 0;
3433: DMPlexGetCone(dm, support[s], &cone);
3434: if (cone[1] == v) r = 1;
3435: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
3436: }
3437: }
3438: DMPlexSetSupport(rdm, newp, supportRef);
3439: #if defined(PETSC_USE_DEBUG)
3440: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3441: for (p = 0; p < size; ++p) {
3442: 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);
3443: }
3444: #endif
3445: }
3446: /* Face vertices have 2 + cells supports */
3447: for (f = fStart; f < fMax; ++f) {
3448: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
3449: const PetscInt *cone, *support;
3450: PetscInt size, s;
3452: DMPlexGetSupportSize(dm, f, &size);
3453: DMPlexGetSupport(dm, f, &support);
3454: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
3455: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
3456: for (s = 0; s < size; ++s) {
3457: PetscInt r = 0;
3459: DMPlexGetCone(dm, support[s], &cone);
3460: if (support[s] >= cMax) {
3461: supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
3462: } else {
3463: if (cone[1] == f) r = 1;
3464: else if (cone[2] == f) r = 2;
3465: else if (cone[3] == f) r = 3;
3466: supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
3467: }
3468: }
3469: DMPlexSetSupport(rdm, newp, supportRef);
3470: #if defined(PETSC_USE_DEBUG)
3471: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
3472: for (p = 0; p < 2+size; ++p) {
3473: 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);
3474: }
3475: #endif
3476: }
3477: /* Cell vertices have 4 supports */
3478: for (c = cStart; c < cMax; ++c) {
3479: const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
3480: PetscInt supportNew[4];
3482: for (r = 0; r < 4; ++r) {
3483: supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
3484: }
3485: DMPlexSetSupport(rdm, newp, supportNew);
3486: }
3487: PetscFree(supportRef);
3488: break;
3489: case REFINER_SIMPLEX_3D:
3490: /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
3491: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
3492: for (c = cStart; c < cEnd; ++c) {
3493: const PetscInt newp = cStartNew + (c - cStart)*8;
3494: const PetscInt *cone, *ornt;
3495: PetscInt coneNew[4], orntNew[4];
3497: DMPlexGetCone(dm, c, &cone);
3498: DMPlexGetConeOrientation(dm, c, &ornt);
3499: /* A tetrahedron: {0, a, c, d} */
3500: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
3501: orntNew[0] = ornt[0];
3502: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
3503: orntNew[1] = ornt[1];
3504: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
3505: orntNew[2] = ornt[2];
3506: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0;
3507: orntNew[3] = 0;
3508: DMPlexSetCone(rdm, newp+0, coneNew);
3509: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3510: #if defined(PETSC_USE_DEBUG)
3511: 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);
3512: for (p = 0; p < 4; ++p) {
3513: 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);
3514: }
3515: #endif
3516: /* B tetrahedron: {a, 1, b, e} */
3517: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
3518: orntNew[0] = ornt[0];
3519: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
3520: orntNew[1] = ornt[1];
3521: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1;
3522: orntNew[2] = 0;
3523: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
3524: orntNew[3] = ornt[3];
3525: DMPlexSetCone(rdm, newp+1, coneNew);
3526: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3527: #if defined(PETSC_USE_DEBUG)
3528: 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);
3529: for (p = 0; p < 4; ++p) {
3530: 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);
3531: }
3532: #endif
3533: /* C tetrahedron: {c, b, 2, f} */
3534: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
3535: orntNew[0] = ornt[0];
3536: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2;
3537: orntNew[1] = 0;
3538: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
3539: orntNew[2] = ornt[2];
3540: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
3541: orntNew[3] = ornt[3];
3542: DMPlexSetCone(rdm, newp+2, coneNew);
3543: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3544: #if defined(PETSC_USE_DEBUG)
3545: 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);
3546: for (p = 0; p < 4; ++p) {
3547: 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);
3548: }
3549: #endif
3550: /* D tetrahedron: {d, e, f, 3} */
3551: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3;
3552: orntNew[0] = 0;
3553: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
3554: orntNew[1] = ornt[1];
3555: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
3556: orntNew[2] = ornt[2];
3557: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
3558: orntNew[3] = ornt[3];
3559: DMPlexSetCone(rdm, newp+3, coneNew);
3560: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3561: #if defined(PETSC_USE_DEBUG)
3562: 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);
3563: for (p = 0; p < 4; ++p) {
3564: 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);
3565: }
3566: #endif
3567: /* A' tetrahedron: {c, d, a, f} */
3568: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0;
3569: orntNew[0] = -3;
3570: coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
3571: orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
3572: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3573: orntNew[2] = 0;
3574: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3575: orntNew[3] = 2;
3576: DMPlexSetCone(rdm, newp+4, coneNew);
3577: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
3578: #if defined(PETSC_USE_DEBUG)
3579: 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);
3580: for (p = 0; p < 4; ++p) {
3581: 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);
3582: }
3583: #endif
3584: /* B' tetrahedron: {e, b, a, f} */
3585: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1;
3586: orntNew[0] = -2;
3587: coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
3588: orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1);
3589: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3590: orntNew[2] = 0;
3591: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3592: orntNew[3] = 0;
3593: DMPlexSetCone(rdm, newp+5, coneNew);
3594: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
3595: #if defined(PETSC_USE_DEBUG)
3596: 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);
3597: for (p = 0; p < 4; ++p) {
3598: 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);
3599: }
3600: #endif
3601: /* C' tetrahedron: {f, a, c, b} */
3602: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3603: orntNew[0] = -2;
3604: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3605: orntNew[1] = -2;
3606: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2;
3607: orntNew[2] = -1;
3608: coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3;
3609: orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
3610: DMPlexSetCone(rdm, newp+6, coneNew);
3611: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
3612: #if defined(PETSC_USE_DEBUG)
3613: 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);
3614: for (p = 0; p < 4; ++p) {
3615: 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);
3616: }
3617: #endif
3618: /* D' tetrahedron: {f, a, e, d} */
3619: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3620: orntNew[0] = -2;
3621: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3622: orntNew[1] = -1;
3623: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3;
3624: orntNew[2] = -2;
3625: coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
3626: orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1);
3627: DMPlexSetCone(rdm, newp+7, coneNew);
3628: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
3629: #if defined(PETSC_USE_DEBUG)
3630: 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);
3631: for (p = 0; p < 4; ++p) {
3632: 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);
3633: }
3634: #endif
3635: }
3636: /* Split faces have 3 edges and the same cells as the parent */
3637: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
3638: PetscMalloc1(2 + maxSupportSize*3, &supportRef);
3639: for (f = fStart; f < fEnd; ++f) {
3640: const PetscInt newp = fStartNew + (f - fStart)*4;
3641: const PetscInt *cone, *ornt, *support;
3642: PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s;
3644: DMPlexGetCone(dm, f, &cone);
3645: DMPlexGetConeOrientation(dm, f, &ornt);
3646: /* A triangle */
3647: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
3648: orntNew[0] = ornt[0];
3649: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
3650: orntNew[1] = -2;
3651: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
3652: orntNew[2] = ornt[2];
3653: DMPlexSetCone(rdm, newp+0, coneNew);
3654: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3655: #if defined(PETSC_USE_DEBUG)
3656: 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);
3657: for (p = 0; p < 3; ++p) {
3658: 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);
3659: }
3660: #endif
3661: /* B triangle */
3662: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
3663: orntNew[0] = ornt[0];
3664: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
3665: orntNew[1] = ornt[1];
3666: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
3667: orntNew[2] = -2;
3668: DMPlexSetCone(rdm, newp+1, coneNew);
3669: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3670: #if defined(PETSC_USE_DEBUG)
3671: 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);
3672: for (p = 0; p < 3; ++p) {
3673: 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);
3674: }
3675: #endif
3676: /* C triangle */
3677: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
3678: orntNew[0] = -2;
3679: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
3680: orntNew[1] = ornt[1];
3681: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
3682: orntNew[2] = ornt[2];
3683: DMPlexSetCone(rdm, newp+2, coneNew);
3684: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3685: #if defined(PETSC_USE_DEBUG)
3686: 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);
3687: for (p = 0; p < 3; ++p) {
3688: 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);
3689: }
3690: #endif
3691: /* D triangle */
3692: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
3693: orntNew[0] = 0;
3694: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
3695: orntNew[1] = 0;
3696: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
3697: orntNew[2] = 0;
3698: DMPlexSetCone(rdm, newp+3, coneNew);
3699: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3700: #if defined(PETSC_USE_DEBUG)
3701: 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);
3702: for (p = 0; p < 3; ++p) {
3703: 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);
3704: }
3705: #endif
3706: DMPlexGetSupportSize(dm, f, &supportSize);
3707: DMPlexGetSupport(dm, f, &support);
3708: for (r = 0; r < 4; ++r) {
3709: for (s = 0; s < supportSize; ++s) {
3710: PetscInt subf;
3711: DMPlexGetConeSize(dm, support[s], &coneSize);
3712: DMPlexGetCone(dm, support[s], &cone);
3713: DMPlexGetConeOrientation(dm, support[s], &ornt);
3714: for (c = 0; c < coneSize; ++c) {
3715: if (cone[c] == f) break;
3716: }
3717: subf = GetTriSubfaceInverse_Static(ornt[c], r);
3718: supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
3719: }
3720: DMPlexSetSupport(rdm, newp+r, supportRef);
3721: #if defined(PETSC_USE_DEBUG)
3722: 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);
3723: for (p = 0; p < supportSize; ++p) {
3724: 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);
3725: }
3726: #endif
3727: }
3728: }
3729: /* Interior faces have 3 edges and 2 cells */
3730: for (c = cStart; c < cEnd; ++c) {
3731: PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
3732: const PetscInt *cone, *ornt;
3733: PetscInt coneNew[3], orntNew[3];
3734: PetscInt supportNew[2];
3736: DMPlexGetCone(dm, c, &cone);
3737: DMPlexGetConeOrientation(dm, c, &ornt);
3738: /* Face A: {c, a, d} */
3739: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3740: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3741: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3742: orntNew[1] = ornt[1] < 0 ? -2 : 0;
3743: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
3744: orntNew[2] = ornt[2] < 0 ? -2 : 0;
3745: DMPlexSetCone(rdm, newp, coneNew);
3746: DMPlexSetConeOrientation(rdm, newp, orntNew);
3747: #if defined(PETSC_USE_DEBUG)
3748: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3749: for (p = 0; p < 3; ++p) {
3750: 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);
3751: }
3752: #endif
3753: supportNew[0] = (c - cStart)*8 + 0;
3754: supportNew[1] = (c - cStart)*8 + 0+4;
3755: DMPlexSetSupport(rdm, newp, supportNew);
3756: #if defined(PETSC_USE_DEBUG)
3757: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3758: for (p = 0; p < 2; ++p) {
3759: 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);
3760: }
3761: #endif
3762: ++newp;
3763: /* Face B: {a, b, e} */
3764: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3765: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3766: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
3767: orntNew[1] = ornt[3] < 0 ? -2 : 0;
3768: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3769: orntNew[2] = ornt[1] < 0 ? -2 : 0;
3770: DMPlexSetCone(rdm, newp, coneNew);
3771: DMPlexSetConeOrientation(rdm, newp, orntNew);
3772: #if defined(PETSC_USE_DEBUG)
3773: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3774: for (p = 0; p < 3; ++p) {
3775: 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);
3776: }
3777: #endif
3778: supportNew[0] = (c - cStart)*8 + 1;
3779: supportNew[1] = (c - cStart)*8 + 1+4;
3780: DMPlexSetSupport(rdm, newp, supportNew);
3781: #if defined(PETSC_USE_DEBUG)
3782: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3783: for (p = 0; p < 2; ++p) {
3784: 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);
3785: }
3786: #endif
3787: ++newp;
3788: /* Face C: {c, f, b} */
3789: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
3790: orntNew[0] = ornt[2] < 0 ? -2 : 0;
3791: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3792: orntNew[1] = ornt[3] < 0 ? -2 : 0;
3793: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
3794: orntNew[2] = ornt[0] < 0 ? -2 : 0;
3795: DMPlexSetCone(rdm, newp, coneNew);
3796: DMPlexSetConeOrientation(rdm, newp, orntNew);
3797: #if defined(PETSC_USE_DEBUG)
3798: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3799: for (p = 0; p < 3; ++p) {
3800: 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);
3801: }
3802: #endif
3803: supportNew[0] = (c - cStart)*8 + 2;
3804: supportNew[1] = (c - cStart)*8 + 2+4;
3805: DMPlexSetSupport(rdm, newp, supportNew);
3806: #if defined(PETSC_USE_DEBUG)
3807: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3808: for (p = 0; p < 2; ++p) {
3809: 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);
3810: }
3811: #endif
3812: ++newp;
3813: /* Face D: {d, e, f} */
3814: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
3815: orntNew[0] = ornt[1] < 0 ? -2 : 0;
3816: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3817: orntNew[1] = ornt[3] < 0 ? -2 : 0;
3818: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3819: orntNew[2] = ornt[2] < 0 ? -2 : 0;
3820: DMPlexSetCone(rdm, newp, coneNew);
3821: DMPlexSetConeOrientation(rdm, newp, orntNew);
3822: #if defined(PETSC_USE_DEBUG)
3823: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3824: for (p = 0; p < 3; ++p) {
3825: 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);
3826: }
3827: #endif
3828: supportNew[0] = (c - cStart)*8 + 3;
3829: supportNew[1] = (c - cStart)*8 + 3+4;
3830: DMPlexSetSupport(rdm, newp, supportNew);
3831: #if defined(PETSC_USE_DEBUG)
3832: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3833: for (p = 0; p < 2; ++p) {
3834: 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);
3835: }
3836: #endif
3837: ++newp;
3838: /* Face E: {d, f, a} */
3839: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3840: orntNew[0] = ornt[2] < 0 ? 0 : -2;
3841: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3842: orntNew[1] = -2;
3843: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3844: orntNew[2] = ornt[1] < 0 ? -2 : 0;
3845: DMPlexSetCone(rdm, newp, coneNew);
3846: DMPlexSetConeOrientation(rdm, newp, orntNew);
3847: #if defined(PETSC_USE_DEBUG)
3848: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3849: for (p = 0; p < 3; ++p) {
3850: 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);
3851: }
3852: #endif
3853: supportNew[0] = (c - cStart)*8 + 0+4;
3854: supportNew[1] = (c - cStart)*8 + 3+4;
3855: DMPlexSetSupport(rdm, newp, supportNew);
3856: #if defined(PETSC_USE_DEBUG)
3857: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3858: for (p = 0; p < 2; ++p) {
3859: 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);
3860: }
3861: #endif
3862: ++newp;
3863: /* Face F: {c, a, f} */
3864: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3865: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3866: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3867: orntNew[1] = 0;
3868: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
3869: orntNew[2] = ornt[2] < 0 ? 0 : -2;
3870: DMPlexSetCone(rdm, newp, coneNew);
3871: DMPlexSetConeOrientation(rdm, newp, orntNew);
3872: #if defined(PETSC_USE_DEBUG)
3873: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3874: for (p = 0; p < 3; ++p) {
3875: 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);
3876: }
3877: #endif
3878: supportNew[0] = (c - cStart)*8 + 0+4;
3879: supportNew[1] = (c - cStart)*8 + 2+4;
3880: DMPlexSetSupport(rdm, newp, supportNew);
3881: #if defined(PETSC_USE_DEBUG)
3882: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3883: for (p = 0; p < 2; ++p) {
3884: 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);
3885: }
3886: #endif
3887: ++newp;
3888: /* Face G: {e, a, f} */
3889: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3890: orntNew[0] = ornt[1] < 0 ? -2 : 0;
3891: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3892: orntNew[1] = 0;
3893: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3894: orntNew[2] = ornt[3] < 0 ? 0 : -2;
3895: DMPlexSetCone(rdm, newp, coneNew);
3896: DMPlexSetConeOrientation(rdm, newp, orntNew);
3897: #if defined(PETSC_USE_DEBUG)
3898: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3899: for (p = 0; p < 3; ++p) {
3900: 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);
3901: }
3902: #endif
3903: supportNew[0] = (c - cStart)*8 + 1+4;
3904: supportNew[1] = (c - cStart)*8 + 3+4;
3905: DMPlexSetSupport(rdm, newp, supportNew);
3906: #if defined(PETSC_USE_DEBUG)
3907: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3908: for (p = 0; p < 2; ++p) {
3909: 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);
3910: }
3911: #endif
3912: ++newp;
3913: /* Face H: {a, b, f} */
3914: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3915: orntNew[0] = ornt[0] < 0 ? -2 : 0;
3916: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3917: orntNew[1] = ornt[3] < 0 ? 0 : -2;
3918: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3919: orntNew[2] = -2;
3920: DMPlexSetCone(rdm, newp, coneNew);
3921: DMPlexSetConeOrientation(rdm, newp, orntNew);
3922: #if defined(PETSC_USE_DEBUG)
3923: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3924: for (p = 0; p < 3; ++p) {
3925: 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);
3926: }
3927: #endif
3928: supportNew[0] = (c - cStart)*8 + 1+4;
3929: supportNew[1] = (c - cStart)*8 + 2+4;
3930: DMPlexSetSupport(rdm, newp, supportNew);
3931: #if defined(PETSC_USE_DEBUG)
3932: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
3933: for (p = 0; p < 2; ++p) {
3934: 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);
3935: }
3936: #endif
3937: ++newp;
3938: }
3939: /* Split Edges have 2 vertices and the same faces as the parent */
3940: for (e = eStart; e < eEnd; ++e) {
3941: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
3943: for (r = 0; r < 2; ++r) {
3944: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
3945: const PetscInt *cone, *ornt, *support;
3946: PetscInt coneNew[2], coneSize, c, supportSize, s;
3948: DMPlexGetCone(dm, e, &cone);
3949: coneNew[0] = vStartNew + (cone[0] - vStart);
3950: coneNew[1] = vStartNew + (cone[1] - vStart);
3951: coneNew[(r+1)%2] = newv;
3952: DMPlexSetCone(rdm, newp, coneNew);
3953: #if defined(PETSC_USE_DEBUG)
3954: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
3955: for (p = 0; p < 2; ++p) {
3956: 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);
3957: }
3958: #endif
3959: DMPlexGetSupportSize(dm, e, &supportSize);
3960: DMPlexGetSupport(dm, e, &support);
3961: for (s = 0; s < supportSize; ++s) {
3962: DMPlexGetConeSize(dm, support[s], &coneSize);
3963: DMPlexGetCone(dm, support[s], &cone);
3964: DMPlexGetConeOrientation(dm, support[s], &ornt);
3965: for (c = 0; c < coneSize; ++c) {
3966: if (cone[c] == e) break;
3967: }
3968: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
3969: }
3970: DMPlexSetSupport(rdm, newp, supportRef);
3971: #if defined(PETSC_USE_DEBUG)
3972: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
3973: for (p = 0; p < supportSize; ++p) {
3974: 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);
3975: }
3976: #endif
3977: }
3978: }
3979: /* Face edges have 2 vertices and 2+cells*(1/2) faces */
3980: for (f = fStart; f < fEnd; ++f) {
3981: const PetscInt *cone, *ornt, *support;
3982: PetscInt coneSize, supportSize, s;
3984: DMPlexGetSupportSize(dm, f, &supportSize);
3985: DMPlexGetSupport(dm, f, &support);
3986: for (r = 0; r < 3; ++r) {
3987: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
3988: PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
3989: PetscInt fint[24] = { 1, 7, -1, -1, 0, 5,
3990: -1, -1, 1, 6, 0, 4,
3991: 2, 5, 3, 4, -1, -1,
3992: -1, -1, 3, 6, 2, 7};
3994: DMPlexGetCone(dm, f, &cone);
3995: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
3996: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
3997: DMPlexSetCone(rdm, newp, coneNew);
3998: #if defined(PETSC_USE_DEBUG)
3999: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
4000: for (p = 0; p < 2; ++p) {
4001: 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);
4002: }
4003: #endif
4004: supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
4005: supportRef[1] = fStartNew + (f - fStart)*4 + 3;
4006: for (s = 0; s < supportSize; ++s) {
4007: DMPlexGetConeSize(dm, support[s], &coneSize);
4008: DMPlexGetCone(dm, support[s], &cone);
4009: DMPlexGetConeOrientation(dm, support[s], &ornt);
4010: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
4011: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4012: er = GetTriMidEdgeInverse_Static(ornt[c], r);
4013: if (er == eint[c]) {
4014: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
4015: } else {
4016: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
4017: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
4018: }
4019: }
4020: DMPlexSetSupport(rdm, newp, supportRef);
4021: #if defined(PETSC_USE_DEBUG)
4022: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
4023: for (p = 0; p < intFaces; ++p) {
4024: 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);
4025: }
4026: #endif
4027: }
4028: }
4029: /* Interior edges have 2 vertices and 4 faces */
4030: for (c = cStart; c < cEnd; ++c) {
4031: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
4032: const PetscInt *cone, *ornt, *fcone;
4033: PetscInt coneNew[2], supportNew[4], find;
4035: DMPlexGetCone(dm, c, &cone);
4036: DMPlexGetConeOrientation(dm, c, &ornt);
4037: DMPlexGetCone(dm, cone[0], &fcone);
4038: find = GetTriEdge_Static(ornt[0], 0);
4039: coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
4040: DMPlexGetCone(dm, cone[2], &fcone);
4041: find = GetTriEdge_Static(ornt[2], 1);
4042: coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
4043: DMPlexSetCone(rdm, newp, coneNew);
4044: #if defined(PETSC_USE_DEBUG)
4045: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
4046: for (p = 0; p < 2; ++p) {
4047: 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);
4048: }
4049: #endif
4050: supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
4051: supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
4052: supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
4053: supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
4054: DMPlexSetSupport(rdm, newp, supportNew);
4055: #if defined(PETSC_USE_DEBUG)
4056: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
4057: for (p = 0; p < 4; ++p) {
4058: 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);
4059: }
4060: #endif
4061: }
4062: /* Old vertices have identical supports */
4063: for (v = vStart; v < vEnd; ++v) {
4064: const PetscInt newp = vStartNew + (v - vStart);
4065: const PetscInt *support, *cone;
4066: PetscInt size, s;
4068: DMPlexGetSupportSize(dm, v, &size);
4069: DMPlexGetSupport(dm, v, &support);
4070: for (s = 0; s < size; ++s) {
4071: PetscInt r = 0;
4073: DMPlexGetCone(dm, support[s], &cone);
4074: if (cone[1] == v) r = 1;
4075: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4076: }
4077: DMPlexSetSupport(rdm, newp, supportRef);
4078: #if defined(PETSC_USE_DEBUG)
4079: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
4080: for (p = 0; p < size; ++p) {
4081: 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);
4082: }
4083: #endif
4084: }
4085: /* Edge vertices have 2 + face*2 + 0/1 supports */
4086: for (e = eStart; e < eEnd; ++e) {
4087: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
4088: const PetscInt *cone, *support;
4089: PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s;
4091: DMPlexGetSupportSize(dm, e, &size);
4092: DMPlexGetSupport(dm, e, &support);
4093: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4094: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4095: for (s = 0; s < size; ++s) {
4096: PetscInt r = 0;
4098: DMPlexGetConeSize(dm, support[s], &coneSize);
4099: DMPlexGetCone(dm, support[s], &cone);
4100: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
4101: supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
4102: supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
4103: }
4104: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
4105: for (s = 0; s < starSize*2; s += 2) {
4106: const PetscInt *cone, *ornt;
4107: PetscInt e01, e23;
4109: if ((star[s] >= cStart) && (star[s] < cEnd)) {
4110: /* Check edge 0-1 */
4111: DMPlexGetCone(dm, star[s], &cone);
4112: DMPlexGetConeOrientation(dm, star[s], &ornt);
4113: DMPlexGetCone(dm, cone[0], &cone);
4114: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
4115: /* Check edge 2-3 */
4116: DMPlexGetCone(dm, star[s], &cone);
4117: DMPlexGetConeOrientation(dm, star[s], &ornt);
4118: DMPlexGetCone(dm, cone[2], &cone);
4119: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
4120: if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
4121: }
4122: }
4123: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
4124: DMPlexSetSupport(rdm, newp, supportRef);
4125: #if defined(PETSC_USE_DEBUG)
4126: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
4127: for (p = 0; p < 2+size*2+cellSize; ++p) {
4128: 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);
4129: }
4130: #endif
4131: }
4132: PetscFree(supportRef);
4133: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
4134: break;
4135: case REFINER_HYBRID_SIMPLEX_3D:
4136: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);
4137: /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
4138: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
4139: for (c = cStart; c < cMax; ++c) {
4140: const PetscInt newp = cStartNew + (c - cStart)*8;
4141: const PetscInt *cone, *ornt;
4142: PetscInt coneNew[4], orntNew[4];
4144: DMPlexGetCone(dm, c, &cone);
4145: DMPlexGetConeOrientation(dm, c, &ornt);
4146: /* A tetrahedron: {0, a, c, d} */
4147: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
4148: orntNew[0] = ornt[0];
4149: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
4150: orntNew[1] = ornt[1];
4151: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
4152: orntNew[2] = ornt[2];
4153: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0;
4154: orntNew[3] = 0;
4155: DMPlexSetCone(rdm, newp+0, coneNew);
4156: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
4157: #if defined(PETSC_USE_DEBUG)
4158: 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);
4159: for (p = 0; p < 4; ++p) {
4160: 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);
4161: }
4162: #endif
4163: /* B tetrahedron: {a, 1, b, e} */
4164: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
4165: orntNew[0] = ornt[0];
4166: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
4167: orntNew[1] = ornt[1];
4168: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1;
4169: orntNew[2] = 0;
4170: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
4171: orntNew[3] = ornt[3];
4172: DMPlexSetCone(rdm, newp+1, coneNew);
4173: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
4174: #if defined(PETSC_USE_DEBUG)
4175: 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);
4176: for (p = 0; p < 4; ++p) {
4177: 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);
4178: }
4179: #endif
4180: /* C tetrahedron: {c, b, 2, f} */
4181: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
4182: orntNew[0] = ornt[0];
4183: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2;
4184: orntNew[1] = 0;
4185: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
4186: orntNew[2] = ornt[2];
4187: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
4188: orntNew[3] = ornt[3];
4189: DMPlexSetCone(rdm, newp+2, coneNew);
4190: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
4191: #if defined(PETSC_USE_DEBUG)
4192: 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);
4193: for (p = 0; p < 4; ++p) {
4194: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew);
4195: }
4196: #endif
4197: /* D tetrahedron: {d, e, f, 3} */
4198: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3;
4199: orntNew[0] = 0;
4200: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
4201: orntNew[1] = ornt[1];
4202: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
4203: orntNew[2] = ornt[2];
4204: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
4205: orntNew[3] = ornt[3];
4206: DMPlexSetCone(rdm, newp+3, coneNew);
4207: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
4208: #if defined(PETSC_USE_DEBUG)
4209: 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);
4210: for (p = 0; p < 4; ++p) {
4211: 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);
4212: }
4213: #endif
4214: /* A' tetrahedron: {d, a, c, f} */
4215: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0;
4216: orntNew[0] = -3;
4217: coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
4218: orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
4219: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
4220: orntNew[2] = 0;
4221: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
4222: orntNew[3] = 2;
4223: DMPlexSetCone(rdm, newp+4, coneNew);
4224: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
4225: #if defined(PETSC_USE_DEBUG)
4226: 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);
4227: for (p = 0; p < 4; ++p) {
4228: 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);
4229: }
4230: #endif
4231: /* B' tetrahedron: {e, b, a, f} */
4232: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1;
4233: orntNew[0] = -3;
4234: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
4235: orntNew[1] = 1;
4236: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
4237: orntNew[2] = 0;
4238: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
4239: orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0);
4240: DMPlexSetCone(rdm, newp+5, coneNew);
4241: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
4242: #if defined(PETSC_USE_DEBUG)
4243: 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);
4244: for (p = 0; p < 4; ++p) {
4245: 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);
4246: }
4247: #endif
4248: /* C' tetrahedron: {b, f, c, a} */
4249: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2;
4250: orntNew[0] = -3;
4251: coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
4252: orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
4253: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
4254: orntNew[2] = -3;
4255: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
4256: orntNew[3] = -2;
4257: DMPlexSetCone(rdm, newp+6, coneNew);
4258: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
4259: #if defined(PETSC_USE_DEBUG)
4260: 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);
4261: for (p = 0; p < 4; ++p) {
4262: 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);
4263: }
4264: #endif
4265: /* D' tetrahedron: {f, e, d, a} */
4266: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3;
4267: orntNew[0] = -3;
4268: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
4269: orntNew[1] = -3;
4270: coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
4271: orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0);
4272: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
4273: orntNew[3] = -3;
4274: DMPlexSetCone(rdm, newp+7, coneNew);
4275: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
4276: #if defined(PETSC_USE_DEBUG)
4277: 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);
4278: for (p = 0; p < 4; ++p) {
4279: 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);
4280: }
4281: #endif
4282: }
4283: /* Hybrid cells have 5 faces */
4284: for (c = cMax; c < cEnd; ++c) {
4285: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
4286: const PetscInt *cone, *ornt, *fornt;
4287: PetscInt coneNew[5], orntNew[5], o, of, i;
4289: DMPlexGetCone(dm, c, &cone);
4290: DMPlexGetConeOrientation(dm, c, &ornt);
4291: DMPlexGetConeOrientation(dm, cone[0], &fornt);
4292: o = ornt[0] < 0 ? -1 : 1;
4293: for (r = 0; r < 3; ++r) {
4294: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
4295: orntNew[0] = ornt[0];
4296: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
4297: orntNew[1] = ornt[1];
4298: of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1;
4299: i = GetTriEdgeInverse_Static(ornt[0], r) + 2;
4300: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0);
4301: orntNew[i] = 0;
4302: i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
4303: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
4304: orntNew[i] = 0;
4305: of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
4306: i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
4307: 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);
4308: orntNew[i] = 0;
4309: DMPlexSetCone(rdm, newp+r, coneNew);
4310: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
4311: #if defined(PETSC_USE_DEBUG)
4312: 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);
4313: for (p = 0; p < 2; ++p) {
4314: 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);
4315: }
4316: for (p = 2; p < 5; ++p) {
4317: 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);
4318: }
4319: #endif
4320: }
4321: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
4322: orntNew[0] = 0;
4323: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
4324: orntNew[1] = 0;
4325: coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
4326: orntNew[2] = 0;
4327: coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
4328: orntNew[3] = 0;
4329: coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
4330: orntNew[4] = 0;
4331: DMPlexSetCone(rdm, newp+3, coneNew);
4332: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
4333: #if defined(PETSC_USE_DEBUG)
4334: 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);
4335: for (p = 0; p < 2; ++p) {
4336: 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);
4337: }
4338: for (p = 2; p < 5; ++p) {
4339: 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);
4340: }
4341: #endif
4342: }
4343: /* Split faces have 3 edges and the same cells as the parent */
4344: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
4345: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
4346: for (f = fStart; f < fMax; ++f) {
4347: const PetscInt newp = fStartNew + (f - fStart)*4;
4348: const PetscInt *cone, *ornt, *support;
4349: PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s;
4351: DMPlexGetCone(dm, f, &cone);
4352: DMPlexGetConeOrientation(dm, f, &ornt);
4353: /* A triangle */
4354: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
4355: orntNew[0] = ornt[0];
4356: coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
4357: orntNew[1] = -2;
4358: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
4359: orntNew[2] = ornt[2];
4360: DMPlexSetCone(rdm, newp+0, coneNew);
4361: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
4362: #if defined(PETSC_USE_DEBUG)
4363: 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);
4364: for (p = 0; p < 3; ++p) {
4365: 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);
4366: }
4367: #endif
4368: /* B triangle */
4369: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
4370: orntNew[0] = ornt[0];
4371: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
4372: orntNew[1] = ornt[1];
4373: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
4374: orntNew[2] = -2;
4375: DMPlexSetCone(rdm, newp+1, coneNew);
4376: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
4377: #if defined(PETSC_USE_DEBUG)
4378: 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);
4379: for (p = 0; p < 3; ++p) {
4380: 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);
4381: }
4382: #endif
4383: /* C triangle */
4384: coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
4385: orntNew[0] = -2;
4386: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
4387: orntNew[1] = ornt[1];
4388: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
4389: orntNew[2] = ornt[2];
4390: DMPlexSetCone(rdm, newp+2, coneNew);
4391: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
4392: #if defined(PETSC_USE_DEBUG)
4393: 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);
4394: for (p = 0; p < 3; ++p) {
4395: 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);
4396: }
4397: #endif
4398: /* D triangle */
4399: coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
4400: orntNew[0] = 0;
4401: coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
4402: orntNew[1] = 0;
4403: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
4404: orntNew[2] = 0;
4405: DMPlexSetCone(rdm, newp+3, coneNew);
4406: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
4407: #if defined(PETSC_USE_DEBUG)
4408: 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);
4409: for (p = 0; p < 3; ++p) {
4410: 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);
4411: }
4412: #endif
4413: DMPlexGetSupportSize(dm, f, &supportSize);
4414: DMPlexGetSupport(dm, f, &support);
4415: for (r = 0; r < 4; ++r) {
4416: for (s = 0; s < supportSize; ++s) {
4417: PetscInt subf;
4418: DMPlexGetConeSize(dm, support[s], &coneSize);
4419: DMPlexGetCone(dm, support[s], &cone);
4420: DMPlexGetConeOrientation(dm, support[s], &ornt);
4421: for (c = 0; c < coneSize; ++c) {
4422: if (cone[c] == f) break;
4423: }
4424: subf = GetTriSubfaceInverse_Static(ornt[c], r);
4425: if (support[s] < cMax) {
4426: supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
4427: } else {
4428: supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
4429: }
4430: }
4431: DMPlexSetSupport(rdm, newp+r, supportRef);
4432: #if defined(PETSC_USE_DEBUG)
4433: 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);
4434: for (p = 0; p < supportSize; ++p) {
4435: 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);
4436: }
4437: #endif
4438: }
4439: }
4440: /* Interior cell faces have 3 edges and 2 cells */
4441: for (c = cStart; c < cMax; ++c) {
4442: PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
4443: const PetscInt *cone, *ornt;
4444: PetscInt coneNew[3], orntNew[3];
4445: PetscInt supportNew[2];
4447: DMPlexGetCone(dm, c, &cone);
4448: DMPlexGetConeOrientation(dm, c, &ornt);
4449: /* Face A: {c, a, d} */
4450: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
4451: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4452: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
4453: orntNew[1] = ornt[1] < 0 ? -2 : 0;
4454: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
4455: orntNew[2] = ornt[2] < 0 ? -2 : 0;
4456: DMPlexSetCone(rdm, newp, coneNew);
4457: DMPlexSetConeOrientation(rdm, newp, orntNew);
4458: #if defined(PETSC_USE_DEBUG)
4459: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4460: for (p = 0; p < 3; ++p) {
4461: 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);
4462: }
4463: #endif
4464: supportNew[0] = (c - cStart)*8 + 0;
4465: supportNew[1] = (c - cStart)*8 + 0+4;
4466: DMPlexSetSupport(rdm, newp, supportNew);
4467: #if defined(PETSC_USE_DEBUG)
4468: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4469: for (p = 0; p < 2; ++p) {
4470: 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);
4471: }
4472: #endif
4473: ++newp;
4474: /* Face B: {a, b, e} */
4475: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
4476: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4477: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
4478: orntNew[1] = ornt[3] < 0 ? -2 : 0;
4479: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
4480: orntNew[2] = ornt[1] < 0 ? -2 : 0;
4481: DMPlexSetCone(rdm, newp, coneNew);
4482: DMPlexSetConeOrientation(rdm, newp, orntNew);
4483: #if defined(PETSC_USE_DEBUG)
4484: 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);
4485: for (p = 0; p < 3; ++p) {
4486: 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);
4487: }
4488: #endif
4489: supportNew[0] = (c - cStart)*8 + 1;
4490: supportNew[1] = (c - cStart)*8 + 1+4;
4491: DMPlexSetSupport(rdm, newp, supportNew);
4492: #if defined(PETSC_USE_DEBUG)
4493: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4494: for (p = 0; p < 2; ++p) {
4495: 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);
4496: }
4497: #endif
4498: ++newp;
4499: /* Face C: {c, f, b} */
4500: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
4501: orntNew[0] = ornt[2] < 0 ? -2 : 0;
4502: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
4503: orntNew[1] = ornt[3] < 0 ? -2 : 0;
4504: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
4505: orntNew[2] = ornt[0] < 0 ? -2 : 0;
4506: DMPlexSetCone(rdm, newp, coneNew);
4507: DMPlexSetConeOrientation(rdm, newp, orntNew);
4508: #if defined(PETSC_USE_DEBUG)
4509: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4510: for (p = 0; p < 3; ++p) {
4511: 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);
4512: }
4513: #endif
4514: supportNew[0] = (c - cStart)*8 + 2;
4515: supportNew[1] = (c - cStart)*8 + 2+4;
4516: DMPlexSetSupport(rdm, newp, supportNew);
4517: #if defined(PETSC_USE_DEBUG)
4518: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4519: for (p = 0; p < 2; ++p) {
4520: 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);
4521: }
4522: #endif
4523: ++newp;
4524: /* Face D: {d, e, f} */
4525: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
4526: orntNew[0] = ornt[1] < 0 ? -2 : 0;
4527: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
4528: orntNew[1] = ornt[3] < 0 ? -2 : 0;
4529: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
4530: orntNew[2] = ornt[2] < 0 ? -2 : 0;
4531: DMPlexSetCone(rdm, newp, coneNew);
4532: DMPlexSetConeOrientation(rdm, newp, orntNew);
4533: #if defined(PETSC_USE_DEBUG)
4534: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4535: for (p = 0; p < 3; ++p) {
4536: 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);
4537: }
4538: #endif
4539: supportNew[0] = (c - cStart)*8 + 3;
4540: supportNew[1] = (c - cStart)*8 + 3+4;
4541: DMPlexSetSupport(rdm, newp, supportNew);
4542: #if defined(PETSC_USE_DEBUG)
4543: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4544: for (p = 0; p < 2; ++p) {
4545: 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);
4546: }
4547: #endif
4548: ++newp;
4549: /* Face E: {d, f, a} */
4550: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
4551: orntNew[0] = ornt[2] < 0 ? 0 : -2;
4552: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4553: orntNew[1] = -2;
4554: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
4555: orntNew[2] = ornt[1] < 0 ? -2 : 0;
4556: DMPlexSetCone(rdm, newp, coneNew);
4557: DMPlexSetConeOrientation(rdm, newp, orntNew);
4558: #if defined(PETSC_USE_DEBUG)
4559: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4560: for (p = 0; p < 3; ++p) {
4561: 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);
4562: }
4563: #endif
4564: supportNew[0] = (c - cStart)*8 + 0+4;
4565: supportNew[1] = (c - cStart)*8 + 3+4;
4566: DMPlexSetSupport(rdm, newp, supportNew);
4567: #if defined(PETSC_USE_DEBUG)
4568: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4569: for (p = 0; p < 2; ++p) {
4570: 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);
4571: }
4572: #endif
4573: ++newp;
4574: /* Face F: {c, a, f} */
4575: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
4576: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4577: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4578: orntNew[1] = 0;
4579: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
4580: orntNew[2] = ornt[2] < 0 ? 0 : -2;
4581: DMPlexSetCone(rdm, newp, coneNew);
4582: DMPlexSetConeOrientation(rdm, newp, orntNew);
4583: #if defined(PETSC_USE_DEBUG)
4584: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4585: for (p = 0; p < 3; ++p) {
4586: 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);
4587: }
4588: #endif
4589: supportNew[0] = (c - cStart)*8 + 0+4;
4590: supportNew[1] = (c - cStart)*8 + 2+4;
4591: DMPlexSetSupport(rdm, newp, supportNew);
4592: #if defined(PETSC_USE_DEBUG)
4593: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4594: for (p = 0; p < 2; ++p) {
4595: 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);
4596: }
4597: #endif
4598: ++newp;
4599: /* Face G: {e, a, f} */
4600: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
4601: orntNew[0] = ornt[1] < 0 ? -2 : 0;
4602: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4603: orntNew[1] = 0;
4604: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
4605: orntNew[2] = ornt[3] < 0 ? 0 : -2;
4606: DMPlexSetCone(rdm, newp, coneNew);
4607: DMPlexSetConeOrientation(rdm, newp, orntNew);
4608: #if defined(PETSC_USE_DEBUG)
4609: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4610: for (p = 0; p < 3; ++p) {
4611: 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);
4612: }
4613: #endif
4614: supportNew[0] = (c - cStart)*8 + 1+4;
4615: supportNew[1] = (c - cStart)*8 + 3+4;
4616: DMPlexSetSupport(rdm, newp, supportNew);
4617: #if defined(PETSC_USE_DEBUG)
4618: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4619: for (p = 0; p < 2; ++p) {
4620: 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);
4621: }
4622: #endif
4623: ++newp;
4624: /* Face H: {a, b, f} */
4625: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
4626: orntNew[0] = ornt[0] < 0 ? -2 : 0;
4627: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
4628: orntNew[1] = ornt[3] < 0 ? 0 : -2;
4629: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4630: orntNew[2] = -2;
4631: DMPlexSetCone(rdm, newp, coneNew);
4632: DMPlexSetConeOrientation(rdm, newp, orntNew);
4633: #if defined(PETSC_USE_DEBUG)
4634: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4635: for (p = 0; p < 3; ++p) {
4636: 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);
4637: }
4638: #endif
4639: supportNew[0] = (c - cStart)*8 + 1+4;
4640: supportNew[1] = (c - cStart)*8 + 2+4;
4641: DMPlexSetSupport(rdm, newp, supportNew);
4642: #if defined(PETSC_USE_DEBUG)
4643: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
4644: for (p = 0; p < 2; ++p) {
4645: 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);
4646: }
4647: #endif
4648: ++newp;
4649: }
4650: /* Hybrid split faces have 4 edges and same cells */
4651: for (f = fMax; f < fEnd; ++f) {
4652: const PetscInt *cone, *ornt, *support;
4653: PetscInt coneNew[4], orntNew[4];
4654: PetscInt supportNew[2], size, s, c;
4656: DMPlexGetCone(dm, f, &cone);
4657: DMPlexGetConeOrientation(dm, f, &ornt);
4658: DMPlexGetSupportSize(dm, f, &size);
4659: DMPlexGetSupport(dm, f, &support);
4660: for (r = 0; r < 2; ++r) {
4661: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
4663: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
4664: orntNew[0] = ornt[0];
4665: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
4666: orntNew[1] = ornt[1];
4667: coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
4668: orntNew[2+r] = 0;
4669: coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
4670: orntNew[3-r] = 0;
4671: DMPlexSetCone(rdm, newp, coneNew);
4672: DMPlexSetConeOrientation(rdm, newp, orntNew);
4673: #if defined(PETSC_USE_DEBUG)
4674: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
4675: for (p = 0; p < 2; ++p) {
4676: 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);
4677: }
4678: for (p = 2; p < 4; ++p) {
4679: 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);
4680: }
4681: #endif
4682: for (s = 0; s < size; ++s) {
4683: const PetscInt *coneCell, *orntCell, *fornt;
4684: PetscInt o, of;
4686: DMPlexGetCone(dm, support[s], &coneCell);
4687: DMPlexGetConeOrientation(dm, support[s], &orntCell);
4688: o = orntCell[0] < 0 ? -1 : 1;
4689: for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
4690: if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]);
4691: DMPlexGetConeOrientation(dm, coneCell[0], &fornt);
4692: of = fornt[c-2] < 0 ? -1 : 1;
4693: supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3;
4694: }
4695: DMPlexSetSupport(rdm, newp, supportNew);
4696: #if defined(PETSC_USE_DEBUG)
4697: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
4698: for (p = 0; p < size; ++p) {
4699: 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);
4700: }
4701: #endif
4702: }
4703: }
4704: /* Hybrid cell faces have 4 edges and 2 cells */
4705: for (c = cMax; c < cEnd; ++c) {
4706: PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
4707: const PetscInt *cone, *ornt;
4708: PetscInt coneNew[4], orntNew[4];
4709: PetscInt supportNew[2];
4711: DMPlexGetCone(dm, c, &cone);
4712: DMPlexGetConeOrientation(dm, c, &ornt);
4713: for (r = 0; r < 3; ++r) {
4714: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
4715: orntNew[0] = 0;
4716: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
4717: orntNew[1] = 0;
4718: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
4719: orntNew[2] = 0;
4720: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax);
4721: orntNew[3] = 0;
4722: DMPlexSetCone(rdm, newp+r, coneNew);
4723: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
4724: #if defined(PETSC_USE_DEBUG)
4725: 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);
4726: for (p = 0; p < 2; ++p) {
4727: 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);
4728: }
4729: for (p = 2; p < 4; ++p) {
4730: 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);
4731: }
4732: #endif
4733: supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
4734: supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
4735: DMPlexSetSupport(rdm, newp+r, supportNew);
4736: #if defined(PETSC_USE_DEBUG)
4737: 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);
4738: for (p = 0; p < 2; ++p) {
4739: 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);
4740: }
4741: #endif
4742: }
4743: }
4744: /* Interior split edges have 2 vertices and the same faces as the parent */
4745: for (e = eStart; e < eMax; ++e) {
4746: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
4748: for (r = 0; r < 2; ++r) {
4749: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
4750: const PetscInt *cone, *ornt, *support;
4751: PetscInt coneNew[2], coneSize, c, supportSize, s;
4753: DMPlexGetCone(dm, e, &cone);
4754: coneNew[0] = vStartNew + (cone[0] - vStart);
4755: coneNew[1] = vStartNew + (cone[1] - vStart);
4756: coneNew[(r+1)%2] = newv;
4757: DMPlexSetCone(rdm, newp, coneNew);
4758: #if defined(PETSC_USE_DEBUG)
4759: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4760: for (p = 0; p < 2; ++p) {
4761: 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);
4762: }
4763: #endif
4764: DMPlexGetSupportSize(dm, e, &supportSize);
4765: DMPlexGetSupport(dm, e, &support);
4766: for (s = 0; s < supportSize; ++s) {
4767: DMPlexGetConeSize(dm, support[s], &coneSize);
4768: DMPlexGetCone(dm, support[s], &cone);
4769: DMPlexGetConeOrientation(dm, support[s], &ornt);
4770: for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
4771: if (support[s] < fMax) {
4772: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
4773: } else {
4774: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
4775: }
4776: }
4777: DMPlexSetSupport(rdm, newp, supportRef);
4778: #if defined(PETSC_USE_DEBUG)
4779: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4780: for (p = 0; p < supportSize; ++p) {
4781: 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);
4782: }
4783: #endif
4784: }
4785: }
4786: /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
4787: for (f = fStart; f < fMax; ++f) {
4788: const PetscInt *cone, *ornt, *support;
4789: PetscInt coneSize, supportSize, s;
4791: DMPlexGetSupportSize(dm, f, &supportSize);
4792: DMPlexGetSupport(dm, f, &support);
4793: for (r = 0; r < 3; ++r) {
4794: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
4795: PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
4796: PetscInt fint[24] = { 1, 7, -1, -1, 0, 5,
4797: -1, -1, 1, 6, 0, 4,
4798: 2, 5, 3, 4, -1, -1,
4799: -1, -1, 3, 6, 2, 7};
4801: DMPlexGetCone(dm, f, &cone);
4802: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
4803: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
4804: DMPlexSetCone(rdm, newp, coneNew);
4805: #if defined(PETSC_USE_DEBUG)
4806: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4807: for (p = 0; p < 2; ++p) {
4808: 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);
4809: }
4810: #endif
4811: supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
4812: supportRef[1] = fStartNew + (f - fStart)*4 + 3;
4813: for (s = 0; s < supportSize; ++s) {
4814: DMPlexGetConeSize(dm, support[s], &coneSize);
4815: DMPlexGetCone(dm, support[s], &cone);
4816: DMPlexGetConeOrientation(dm, support[s], &ornt);
4817: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
4818: if (support[s] < cMax) {
4819: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4820: er = GetTriMidEdgeInverse_Static(ornt[c], r);
4821: if (er == eint[c]) {
4822: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
4823: } else {
4824: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
4825: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
4826: }
4827: } else {
4828: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
4829: }
4830: }
4831: DMPlexSetSupport(rdm, newp, supportRef);
4832: #if defined(PETSC_USE_DEBUG)
4833: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4834: for (p = 0; p < intFaces; ++p) {
4835: 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);
4836: }
4837: #endif
4838: }
4839: }
4840: /* Interior cell edges have 2 vertices and 4 faces */
4841: for (c = cStart; c < cMax; ++c) {
4842: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
4843: const PetscInt *cone, *ornt, *fcone;
4844: PetscInt coneNew[2], supportNew[4], find;
4846: DMPlexGetCone(dm, c, &cone);
4847: DMPlexGetConeOrientation(dm, c, &ornt);
4848: DMPlexGetCone(dm, cone[0], &fcone);
4849: find = GetTriEdge_Static(ornt[0], 0);
4850: coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
4851: DMPlexGetCone(dm, cone[2], &fcone);
4852: find = GetTriEdge_Static(ornt[2], 1);
4853: coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
4854: DMPlexSetCone(rdm, newp, coneNew);
4855: #if defined(PETSC_USE_DEBUG)
4856: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4857: for (p = 0; p < 2; ++p) {
4858: 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);
4859: }
4860: #endif
4861: supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
4862: supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
4863: supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
4864: supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
4865: DMPlexSetSupport(rdm, newp, supportNew);
4866: #if defined(PETSC_USE_DEBUG)
4867: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
4868: for (p = 0; p < 4; ++p) {
4869: 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);
4870: }
4871: #endif
4872: }
4873: /* Hybrid edges have two vertices and the same faces */
4874: for (e = eMax; e < eEnd; ++e) {
4875: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
4876: const PetscInt *cone, *support, *fcone;
4877: PetscInt coneNew[2], size, fsize, s;
4879: DMPlexGetCone(dm, e, &cone);
4880: DMPlexGetSupportSize(dm, e, &size);
4881: DMPlexGetSupport(dm, e, &support);
4882: coneNew[0] = vStartNew + (cone[0] - vStart);
4883: coneNew[1] = vStartNew + (cone[1] - vStart);
4884: DMPlexSetCone(rdm, newp, coneNew);
4885: #if defined(PETSC_USE_DEBUG)
4886: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4887: for (p = 0; p < 2; ++p) {
4888: 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);
4889: }
4890: #endif
4891: for (s = 0; s < size; ++s) {
4892: DMPlexGetConeSize(dm, support[s], &fsize);
4893: DMPlexGetCone(dm, support[s], &fcone);
4894: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
4895: if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]);
4896: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
4897: }
4898: DMPlexSetSupport(rdm, newp, supportRef);
4899: #if defined(PETSC_USE_DEBUG)
4900: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4901: for (p = 0; p < size; ++p) {
4902: 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);
4903: }
4904: #endif
4905: }
4906: /* Hybrid face edges have 2 vertices and 2+2*cells faces */
4907: for (f = fMax; f < fEnd; ++f) {
4908: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
4909: const PetscInt *cone, *support, *ccone, *cornt;
4910: PetscInt coneNew[2], size, csize, s;
4912: DMPlexGetCone(dm, f, &cone);
4913: DMPlexGetSupportSize(dm, f, &size);
4914: DMPlexGetSupport(dm, f, &support);
4915: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
4916: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
4917: DMPlexSetCone(rdm, newp, coneNew);
4918: #if defined(PETSC_USE_DEBUG)
4919: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4920: for (p = 0; p < 2; ++p) {
4921: 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);
4922: }
4923: #endif
4924: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
4925: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
4926: for (s = 0; s < size; ++s) {
4927: DMPlexGetConeSize(dm, support[s], &csize);
4928: DMPlexGetCone(dm, support[s], &ccone);
4929: DMPlexGetConeOrientation(dm, support[s], &cornt);
4930: for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
4931: 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]);
4932: supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
4933: supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
4934: }
4935: DMPlexSetSupport(rdm, newp, supportRef);
4936: #if defined(PETSC_USE_DEBUG)
4937: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
4938: for (p = 0; p < 2+size*2; ++p) {
4939: 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);
4940: }
4941: #endif
4942: }
4943: /* Interior vertices have identical supports */
4944: for (v = vStart; v < vEnd; ++v) {
4945: const PetscInt newp = vStartNew + (v - vStart);
4946: const PetscInt *support, *cone;
4947: PetscInt size, s;
4949: DMPlexGetSupportSize(dm, v, &size);
4950: DMPlexGetSupport(dm, v, &support);
4951: for (s = 0; s < size; ++s) {
4952: PetscInt r = 0;
4954: DMPlexGetCone(dm, support[s], &cone);
4955: if (cone[1] == v) r = 1;
4956: if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4957: else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
4958: }
4959: DMPlexSetSupport(rdm, newp, supportRef);
4960: #if defined(PETSC_USE_DEBUG)
4961: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
4962: for (p = 0; p < size; ++p) {
4963: 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);
4964: }
4965: #endif
4966: }
4967: /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
4968: for (e = eStart; e < eMax; ++e) {
4969: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
4970: const PetscInt *cone, *support;
4971: PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
4973: DMPlexGetSupportSize(dm, e, &size);
4974: DMPlexGetSupport(dm, e, &support);
4975: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4976: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4977: for (s = 0; s < size; ++s) {
4978: PetscInt r = 0;
4980: if (support[s] < fMax) {
4981: DMPlexGetConeSize(dm, support[s], &coneSize);
4982: DMPlexGetCone(dm, support[s], &cone);
4983: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
4984: supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
4985: supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
4986: faceSize += 2;
4987: } else {
4988: supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
4989: ++faceSize;
4990: }
4991: }
4992: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
4993: for (s = 0; s < starSize*2; s += 2) {
4994: const PetscInt *cone, *ornt;
4995: PetscInt e01, e23;
4997: if ((star[s] >= cStart) && (star[s] < cMax)) {
4998: /* Check edge 0-1 */
4999: DMPlexGetCone(dm, star[s], &cone);
5000: DMPlexGetConeOrientation(dm, star[s], &ornt);
5001: DMPlexGetCone(dm, cone[0], &cone);
5002: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
5003: /* Check edge 2-3 */
5004: DMPlexGetCone(dm, star[s], &cone);
5005: DMPlexGetConeOrientation(dm, star[s], &ornt);
5006: DMPlexGetCone(dm, cone[2], &cone);
5007: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
5008: if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
5009: }
5010: }
5011: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
5012: DMPlexSetSupport(rdm, newp, supportRef);
5013: #if defined(PETSC_USE_DEBUG)
5014: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5015: for (p = 0; p < 2+faceSize+cellSize; ++p) {
5016: 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);
5017: }
5018: #endif
5019: }
5020: PetscFree(supportRef);
5021: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
5022: break;
5023: case REFINER_SIMPLEX_TO_HEX_3D:
5024: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
5025: /* All cells have 6 faces */
5026: for (c = cStart; c < cEnd; ++c) {
5027: const PetscInt newp = cStartNew + (c - cStart)*4;
5028: const PetscInt *cone, *ornt;
5029: PetscInt coneNew[6];
5030: PetscInt orntNew[6];
5032: DMPlexGetCone(dm, c, &cone);
5033: DMPlexGetConeOrientation(dm, c, &ornt);
5034: /* A hex */
5035: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
5036: orntNew[0] = ornt[0] < 0 ? -1 : 1;
5037: coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */
5038: orntNew[1] = -4;
5039: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */
5040: orntNew[2] = ornt[2] < 0 ? -1 : 1;
5041: coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */
5042: orntNew[3] = -1;
5043: coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */
5044: orntNew[4] = 0;
5045: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */
5046: orntNew[5] = ornt[1] < 0 ? -1 : 1;
5047: DMPlexSetCone(rdm, newp+0, coneNew);
5048: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5049: #if defined(PETSC_USE_DEBUG)
5050: 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);
5051: for (p = 0; p < 6; ++p) {
5052: 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);
5053: }
5054: #endif
5055: /* B hex */
5056: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
5057: orntNew[0] = ornt[0] < 0 ? -2 : 0;
5058: coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */
5059: orntNew[1] = 0;
5060: coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */
5061: orntNew[2] = 0;
5062: coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */
5063: orntNew[3] = ornt[3] < 0 ? -2 : 0;
5064: coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */
5065: orntNew[4] = 0;
5066: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */
5067: orntNew[5] = ornt[1] < 0 ? -4 : 2;
5068: DMPlexSetCone(rdm, newp+1, coneNew);
5069: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5070: #if defined(PETSC_USE_DEBUG)
5071: 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);
5072: for (p = 0; p < 6; ++p) {
5073: 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);
5074: }
5075: #endif
5076: /* C hex */
5077: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
5078: orntNew[0] = ornt[0] < 0 ? -4 : 2;
5079: coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */
5080: orntNew[1] = -4;
5081: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */
5082: orntNew[2] = ornt[2] < 0 ? -2 : 0;
5083: coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */
5084: orntNew[3] = -1;
5085: coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */
5086: orntNew[4] = ornt[3] < 0 ? -1 : 1;
5087: coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */
5088: orntNew[5] = -4;
5089: DMPlexSetCone(rdm, newp+2, coneNew);
5090: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5091: #if defined(PETSC_USE_DEBUG)
5092: 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);
5093: for (p = 0; p < 6; ++p) {
5094: 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);
5095: }
5096: #endif
5097: /* D hex */
5098: coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */
5099: orntNew[0] = 0;
5100: coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */
5101: orntNew[1] = ornt[3] < 0 ? -1 : 1;
5102: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */
5103: orntNew[2] = ornt[2] < 0 ? -4 : 2;
5104: coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */
5105: orntNew[3] = -1;
5106: coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */
5107: orntNew[4] = 0;
5108: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */
5109: orntNew[5] = ornt[1] < 0 ? -2 : 0;
5110: DMPlexSetCone(rdm, newp+3, coneNew);
5111: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
5112: #if defined(PETSC_USE_DEBUG)
5113: 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);
5114: for (p = 0; p < 6; ++p) {
5115: 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);
5116: }
5117: #endif
5118: }
5119: /* Split faces have 4 edges and the same cells as the parent */
5120: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
5121: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
5122: for (f = fStart; f < fEnd; ++f) {
5123: const PetscInt newp = fStartNew + (f - fStart)*3;
5124: const PetscInt *cone, *ornt, *support;
5125: PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s;
5127: DMPlexGetCone(dm, f, &cone);
5128: DMPlexGetConeOrientation(dm, f, &ornt);
5129: /* A quad */
5130: coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
5131: orntNew[0] = ornt[2];
5132: coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
5133: orntNew[1] = ornt[0];
5134: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
5135: orntNew[2] = 0;
5136: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
5137: orntNew[3] = -2;
5138: DMPlexSetCone(rdm, newp+0, coneNew);
5139: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5140: #if defined(PETSC_USE_DEBUG)
5141: 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);
5142: for (p = 0; p < 4; ++p) {
5143: 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);
5144: }
5145: #endif
5146: /* B quad */
5147: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
5148: orntNew[0] = ornt[0];
5149: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
5150: orntNew[1] = ornt[1];
5151: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
5152: orntNew[2] = 0;
5153: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
5154: orntNew[3] = -2;
5155: DMPlexSetCone(rdm, newp+1, coneNew);
5156: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5157: #if defined(PETSC_USE_DEBUG)
5158: 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);
5159: for (p = 0; p < 4; ++p) {
5160: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew);
5161: }
5162: #endif
5163: /* C quad */
5164: coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
5165: orntNew[0] = ornt[1];
5166: coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
5167: orntNew[1] = ornt[2];
5168: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
5169: orntNew[2] = 0;
5170: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
5171: orntNew[3] = -2;
5172: DMPlexSetCone(rdm, newp+2, coneNew);
5173: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5174: #if defined(PETSC_USE_DEBUG)
5175: 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);
5176: for (p = 0; p < 4; ++p) {
5177: 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);
5178: }
5179: #endif
5180: DMPlexGetSupportSize(dm, f, &supportSize);
5181: DMPlexGetSupport(dm, f, &support);
5182: for (r = 0; r < 3; ++r) {
5183: for (s = 0; s < supportSize; ++s) {
5184: PetscInt subf;
5185: DMPlexGetConeSize(dm, support[s], &coneSize);
5186: DMPlexGetCone(dm, support[s], &cone);
5187: DMPlexGetConeOrientation(dm, support[s], &ornt);
5188: for (c = 0; c < coneSize; ++c) {
5189: if (cone[c] == f) break;
5190: }
5191: subf = GetTriSubfaceInverse_Static(ornt[c], r);
5192: supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf];
5193: }
5194: DMPlexSetSupport(rdm, newp+r, supportRef);
5195: #if defined(PETSC_USE_DEBUG)
5196: 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);
5197: for (p = 0; p < supportSize; ++p) {
5198: 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);
5199: }
5200: #endif
5201: }
5202: }
5203: /* Interior faces have 4 edges and 2 cells */
5204: for (c = cStart; c < cEnd; ++c) {
5205: PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6;
5206: const PetscInt *cone, *ornt;
5207: PetscInt coneNew[4], orntNew[4];
5208: PetscInt supportNew[2];
5210: DMPlexGetCone(dm, c, &cone);
5211: DMPlexGetConeOrientation(dm, c, &ornt);
5212: /* Face {a, g, m, h} */
5213: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
5214: orntNew[0] = 0;
5215: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5216: orntNew[1] = 0;
5217: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5218: orntNew[2] = -2;
5219: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
5220: orntNew[3] = -2;
5221: DMPlexSetCone(rdm, newp, coneNew);
5222: DMPlexSetConeOrientation(rdm, newp, orntNew);
5223: #if defined(PETSC_USE_DEBUG)
5224: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5225: for (p = 0; p < 4; ++p) {
5226: 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);
5227: }
5228: #endif
5229: supportNew[0] = (c - cStart)*4 + 0;
5230: supportNew[1] = (c - cStart)*4 + 1;
5231: DMPlexSetSupport(rdm, newp, supportNew);
5232: #if defined(PETSC_USE_DEBUG)
5233: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5234: for (p = 0; p < 2; ++p) {
5235: 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);
5236: }
5237: #endif
5238: ++newp;
5239: /* Face {g, b, l , m} */
5240: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
5241: orntNew[0] = -2;
5242: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0);
5243: orntNew[1] = 0;
5244: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5245: orntNew[2] = 0;
5246: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5247: orntNew[3] = -2;
5248: DMPlexSetCone(rdm, newp, coneNew);
5249: DMPlexSetConeOrientation(rdm, newp, orntNew);
5250: #if defined(PETSC_USE_DEBUG)
5251: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5252: for (p = 0; p < 4; ++p) {
5253: 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);
5254: }
5255: #endif
5256: supportNew[0] = (c - cStart)*4 + 1;
5257: supportNew[1] = (c - cStart)*4 + 2;
5258: DMPlexSetSupport(rdm, newp, supportNew);
5259: #if defined(PETSC_USE_DEBUG)
5260: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5261: for (p = 0; p < 2; ++p) {
5262: 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);
5263: }
5264: #endif
5265: ++newp;
5266: /* Face {c, g, m, i} */
5267: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
5268: orntNew[0] = 0;
5269: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5270: orntNew[1] = 0;
5271: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5272: orntNew[2] = -2;
5273: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0);
5274: orntNew[3] = -2;
5275: DMPlexSetCone(rdm, newp, coneNew);
5276: DMPlexSetConeOrientation(rdm, newp, orntNew);
5277: #if defined(PETSC_USE_DEBUG)
5278: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5279: for (p = 0; p < 4; ++p) {
5280: 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);
5281: }
5282: #endif
5283: supportNew[0] = (c - cStart)*4 + 0;
5284: supportNew[1] = (c - cStart)*4 + 2;
5285: DMPlexSetSupport(rdm, newp, supportNew);
5286: #if defined(PETSC_USE_DEBUG)
5287: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5288: for (p = 0; p < 2; ++p) {
5289: 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);
5290: }
5291: #endif
5292: ++newp;
5293: /* Face {d, h, m, i} */
5294: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
5295: orntNew[0] = 0;
5296: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5297: orntNew[1] = 0;
5298: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5299: orntNew[2] = -2;
5300: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2);
5301: orntNew[3] = -2;
5302: DMPlexSetCone(rdm, newp, coneNew);
5303: DMPlexSetConeOrientation(rdm, newp, orntNew);
5304: #if defined(PETSC_USE_DEBUG)
5305: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5306: for (p = 0; p < 4; ++p) {
5307: 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);
5308: }
5309: #endif
5310: supportNew[0] = (c - cStart)*4 + 0;
5311: supportNew[1] = (c - cStart)*4 + 3;
5312: DMPlexSetSupport(rdm, newp, supportNew);
5313: #if defined(PETSC_USE_DEBUG)
5314: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5315: for (p = 0; p < 2; ++p) {
5316: 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);
5317: }
5318: #endif
5319: ++newp;
5320: /* Face {h, m, l, e} */
5321: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5322: orntNew[0] = 0;
5323: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5324: orntNew[1] = -2;
5325: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1);
5326: orntNew[2] = -2;
5327: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
5328: orntNew[3] = 0;
5329: DMPlexSetCone(rdm, newp, coneNew);
5330: DMPlexSetConeOrientation(rdm, newp, orntNew);
5331: #if defined(PETSC_USE_DEBUG)
5332: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5333: for (p = 0; p < 4; ++p) {
5334: 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);
5335: }
5336: #endif
5337: supportNew[0] = (c - cStart)*4 + 1;
5338: supportNew[1] = (c - cStart)*4 + 3;
5339: DMPlexSetSupport(rdm, newp, supportNew);
5340: #if defined(PETSC_USE_DEBUG)
5341: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5342: for (p = 0; p < 2; ++p) {
5343: 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);
5344: }
5345: #endif
5346: ++newp;
5347: /* Face {i, m, l, f} */
5348: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5349: orntNew[0] = 0;
5350: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5351: orntNew[1] = -2;
5352: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2);
5353: orntNew[2] = -2;
5354: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1);
5355: orntNew[3] = 0;
5356: DMPlexSetCone(rdm, newp, coneNew);
5357: DMPlexSetConeOrientation(rdm, newp, orntNew);
5358: #if defined(PETSC_USE_DEBUG)
5359: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5360: for (p = 0; p < 4; ++p) {
5361: 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);
5362: }
5363: #endif
5364: supportNew[0] = (c - cStart)*4 + 2;
5365: supportNew[1] = (c - cStart)*4 + 3;
5366: DMPlexSetSupport(rdm, newp, supportNew);
5367: #if defined(PETSC_USE_DEBUG)
5368: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5369: for (p = 0; p < 2; ++p) {
5370: 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);
5371: }
5372: #endif
5373: ++newp;
5374: }
5375: /* Split Edges have 2 vertices and the same faces as the parent */
5376: for (e = eStart; e < eEnd; ++e) {
5377: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
5379: for (r = 0; r < 2; ++r) {
5380: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
5381: const PetscInt *cone, *ornt, *support;
5382: PetscInt coneNew[2], coneSize, c, supportSize, s;
5384: DMPlexGetCone(dm, e, &cone);
5385: coneNew[0] = vStartNew + (cone[0] - vStart);
5386: coneNew[1] = vStartNew + (cone[1] - vStart);
5387: coneNew[(r+1)%2] = newv;
5388: DMPlexSetCone(rdm, newp, coneNew);
5389: #if defined(PETSC_USE_DEBUG)
5390: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5391: for (p = 0; p < 2; ++p) {
5392: 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);
5393: }
5394: #endif
5395: DMPlexGetSupportSize(dm, e, &supportSize);
5396: DMPlexGetSupport(dm, e, &support);
5397: for (s = 0; s < supportSize; ++s) {
5398: DMPlexGetConeSize(dm, support[s], &coneSize);
5399: DMPlexGetCone(dm, support[s], &cone);
5400: DMPlexGetConeOrientation(dm, support[s], &ornt);
5401: for (c = 0; c < coneSize; ++c) {
5402: if (cone[c] == e) break;
5403: }
5404: supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3;
5405: }
5406: DMPlexSetSupport(rdm, newp, supportRef);
5407: #if defined(PETSC_USE_DEBUG)
5408: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5409: for (p = 0; p < supportSize; ++p) {
5410: 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);
5411: }
5412: #endif
5413: }
5414: }
5415: /* Face edges have 2 vertices and 2 + cell faces supports */
5416: for (f = fStart; f < fEnd; ++f) {
5417: const PetscInt *cone, *ornt, *support;
5418: PetscInt coneSize, supportSize, s;
5420: DMPlexGetSupportSize(dm, f, &supportSize);
5421: DMPlexGetSupport(dm, f, &support);
5422: for (r = 0; r < 3; ++r) {
5423: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
5424: PetscInt coneNew[2];
5425: PetscInt fint[4][3] = { {0, 1, 2},
5426: {3, 4, 0},
5427: {2, 5, 3},
5428: {1, 4, 5} };
5430: DMPlexGetCone(dm, f, &cone);
5431: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
5432: coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
5433: DMPlexSetCone(rdm, newp, coneNew);
5434: #if defined(PETSC_USE_DEBUG)
5435: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5436: for (p = 0; p < 2; ++p) {
5437: 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);
5438: }
5439: #endif
5440: supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3;
5441: supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3;
5442: for (s = 0; s < supportSize; ++s) {
5443: PetscInt er;
5444: DMPlexGetConeSize(dm, support[s], &coneSize);
5445: DMPlexGetCone(dm, support[s], &cone);
5446: DMPlexGetConeOrientation(dm, support[s], &ornt);
5447: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
5448: er = GetTriInteriorEdgeInverse_Static(ornt[c], r);
5449: supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er];
5450: }
5451: DMPlexSetSupport(rdm, newp, supportRef);
5452: #if defined(PETSC_USE_DEBUG)
5453: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5454: for (p = 0; p < supportSize + 2; ++p) {
5455: 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);
5456: }
5457: #endif
5458: }
5459: }
5460: /* Interior cell edges have 2 vertices and 3 faces */
5461: for (c = cStart; c < cEnd; ++c) {
5462: const PetscInt *cone;
5463: PetscInt fint[4][3] = { {0,1,2},
5464: {0,3,4},
5465: {2,3,5},
5466: {1,4,5} } ;
5468: DMPlexGetCone(dm, c, &cone);
5469: for (r = 0; r < 4; r++) {
5470: PetscInt coneNew[2], supportNew[3];
5471: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
5473: coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
5474: coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart;
5475: DMPlexSetCone(rdm, newp, coneNew);
5476: #if defined(PETSC_USE_DEBUG)
5477: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5478: for (p = 0; p < 2; ++p) {
5479: 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);
5480: }
5481: #endif
5482: supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0];
5483: supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1];
5484: supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2];
5485: DMPlexSetSupport(rdm, newp, supportNew);
5486: #if defined(PETSC_USE_DEBUG)
5487: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
5488: for (p = 0; p < 3; ++p) {
5489: 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);
5490: }
5491: #endif
5492: }
5493: }
5494: /* Old vertices have identical supports */
5495: for (v = vStart; v < vEnd; ++v) {
5496: const PetscInt newp = vStartNew + (v - vStart);
5497: const PetscInt *support, *cone;
5498: PetscInt size, s;
5500: DMPlexGetSupportSize(dm, v, &size);
5501: DMPlexGetSupport(dm, v, &support);
5502: for (s = 0; s < size; ++s) {
5503: PetscInt r = 0;
5505: DMPlexGetCone(dm, support[s], &cone);
5506: if (cone[1] == v) r = 1;
5507: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
5508: }
5509: DMPlexSetSupport(rdm, newp, supportRef);
5510: #if defined(PETSC_USE_DEBUG)
5511: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5512: for (p = 0; p < size; ++p) {
5513: 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);
5514: }
5515: #endif
5516: }
5517: /* Edge vertices have 2 + faces supports */
5518: for (e = eStart; e < eEnd; ++e) {
5519: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
5520: const PetscInt *cone, *support;
5521: PetscInt size, s;
5523: DMPlexGetSupportSize(dm, e, &size);
5524: DMPlexGetSupport(dm, e, &support);
5525: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
5526: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
5527: for (s = 0; s < size; ++s) {
5528: PetscInt r = 0, coneSize;
5530: DMPlexGetConeSize(dm, support[s], &coneSize);
5531: DMPlexGetCone(dm, support[s], &cone);
5532: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
5533: supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r;
5534: }
5535: DMPlexSetSupport(rdm, newp, supportRef);
5536: #if defined(PETSC_USE_DEBUG)
5537: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5538: for (p = 0; p < 2+size; ++p) {
5539: 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);
5540: }
5541: #endif
5542: }
5543: /* Face vertices have 3 + cells supports */
5544: for (f = fStart; f < fEnd; ++f) {
5545: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
5546: const PetscInt *cone, *support;
5547: PetscInt size, s;
5549: DMPlexGetSupportSize(dm, f, &size);
5550: DMPlexGetSupport(dm, f, &support);
5551: supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
5552: supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
5553: supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
5554: for (s = 0; s < size; ++s) {
5555: PetscInt r = 0, coneSize;
5557: DMPlexGetConeSize(dm, support[s], &coneSize);
5558: DMPlexGetCone(dm, support[s], &cone);
5559: for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;}
5560: supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r;
5561: }
5562: DMPlexSetSupport(rdm, newp, supportRef);
5563: #if defined(PETSC_USE_DEBUG)
5564: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5565: for (p = 0; p < 3+size; ++p) {
5566: 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);
5567: }
5568: #endif
5569: }
5570: /* Interior cell vertices have 4 supports */
5571: for (c = cStart; c < cEnd; ++c) {
5572: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart;
5573: supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
5574: supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
5575: supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
5576: supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
5577: DMPlexSetSupport(rdm, newp, supportRef);
5578: #if defined(PETSC_USE_DEBUG)
5579: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
5580: for (p = 0; p < 4; ++p) {
5581: 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);
5582: }
5583: #endif
5584: }
5585: PetscFree(supportRef);
5586: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
5587: break;
5588: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
5589: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
5590: cMax = PetscMin(cEnd, cMax);
5591: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
5592: fMax = PetscMin(fEnd, fMax);
5593: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
5594: eMax = PetscMin(eEnd, eMax);
5595: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
5596: /* All cells have 6 faces */
5597: for (c = cStart; c < cMax; ++c) {
5598: const PetscInt newp = cStartNew + (c - cStart)*4;
5599: const PetscInt *cone, *ornt;
5600: PetscInt coneNew[6];
5601: PetscInt orntNew[6];
5603: DMPlexGetCone(dm, c, &cone);
5604: #if defined(PETSC_USE_DEBUG)
5605: for (p = 0; p < 4; ++p) {
5606: 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);
5607: }
5608: #endif
5609: DMPlexGetConeOrientation(dm, c, &ornt);
5610: /* A hex */
5611: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
5612: orntNew[0] = ornt[0] < 0 ? -1 : 1;
5613: coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* T */
5614: orntNew[1] = -4;
5615: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */
5616: orntNew[2] = ornt[2] < 0 ? -1 : 1;
5617: coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* K */
5618: orntNew[3] = -1;
5619: coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* R */
5620: orntNew[4] = 0;
5621: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */
5622: orntNew[5] = ornt[1] < 0 ? -1 : 1;
5623: DMPlexSetCone(rdm, newp+0, coneNew);
5624: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5625: #if defined(PETSC_USE_DEBUG)
5626: 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);
5627: for (p = 0; p < 6; ++p) {
5628: 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);
5629: }
5630: #endif
5631: /* B hex */
5632: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
5633: orntNew[0] = ornt[0] < 0 ? -2 : 0;
5634: coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* T */
5635: orntNew[1] = 0;
5636: coneNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* F */
5637: orntNew[2] = 0;
5638: coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */
5639: orntNew[3] = ornt[3] < 0 ? -2 : 0;
5640: coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* R */
5641: orntNew[4] = 0;
5642: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */
5643: orntNew[5] = ornt[1] < 0 ? -4 : 2;
5644: DMPlexSetCone(rdm, newp+1, coneNew);
5645: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5646: #if defined(PETSC_USE_DEBUG)
5647: 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);
5648: for (p = 0; p < 6; ++p) {
5649: 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);
5650: }
5651: #endif
5652: /* C hex */
5653: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
5654: orntNew[0] = ornt[0] < 0 ? -4 : 2;
5655: coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* T */
5656: orntNew[1] = -4;
5657: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */
5658: orntNew[2] = ornt[2] < 0 ? -2 : 0;
5659: coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* K */
5660: orntNew[3] = -1;
5661: coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */
5662: orntNew[4] = ornt[3] < 0 ? -1 : 1;
5663: coneNew[5] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* L */
5664: orntNew[5] = -4;
5665: DMPlexSetCone(rdm, newp+2, coneNew);
5666: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5667: #if defined(PETSC_USE_DEBUG)
5668: 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);
5669: for (p = 0; p < 6; ++p) {
5670: 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);
5671: }
5672: #endif
5673: /* D hex */
5674: coneNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* B */
5675: orntNew[0] = 0;
5676: coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */
5677: orntNew[1] = ornt[3] < 0 ? -1 : 1;
5678: coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */
5679: orntNew[2] = ornt[2] < 0 ? -4 : 2;
5680: coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* K */
5681: orntNew[3] = -1;
5682: coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* R */
5683: orntNew[4] = 0;
5684: coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */
5685: orntNew[5] = ornt[1] < 0 ? -2 : 0;
5686: DMPlexSetCone(rdm, newp+3, coneNew);
5687: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
5688: #if defined(PETSC_USE_DEBUG)
5689: 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);
5690: for (p = 0; p < 6; ++p) {
5691: 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);
5692: }
5693: #endif
5694: }
5695: for (c = cMax; c < cEnd; ++c) {
5696: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3;
5697: const PetscInt *cone, *ornt;
5698: PetscInt coneNew[6], orntNew[6];
5699: PetscInt o, of, cf;
5701: DMPlexGetCone(dm, c, &cone);
5702: #if defined(PETSC_USE_DEBUG)
5703: 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);
5704: 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);
5705: 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);
5706: 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);
5707: 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);
5708: #endif
5709: DMPlexGetConeOrientation(dm, c, &ornt);
5710: o = ornt[0] < 0 ? -1 : 1;
5711: o = 1;
5712: /* A hex */
5713: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
5714: orntNew[0] = ornt[0] < 0 ? -1 : 1;
5715: coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* T */
5716: orntNew[1] = ornt[1] < 0 ? 1 : -1;
5717: cf = 2;
5718: of = ornt[2+cf] < 0 ? -1 : 1;
5719: coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* F */
5720: orntNew[2] = o*of < 0 ? 0 : -1;
5721: coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* K */
5722: orntNew[3] = -1;
5723: coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* R */
5724: orntNew[4] = 0;
5725: cf = 0;
5726: of = ornt[2+cf] < 0 ? -1 : 1;
5727: coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* L */
5728: orntNew[5] = o*of < 0 ? 1 : -4;
5729: DMPlexSetCone(rdm, newp+0, coneNew);
5730: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5731: #if defined(PETSC_USE_DEBUG)
5732: 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);
5733: for (p = 0; p < 6; ++p) {
5734: 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);
5735: }
5736: #endif
5737: /* B hex */
5738: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
5739: orntNew[0] = ornt[0] < 0 ? -2 : 0;
5740: coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* T */
5741: orntNew[1] = ornt[1] < 0 ? 2 : -4;
5742: coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* F */
5743: orntNew[2] = 0;
5744: cf = 1;
5745: of = ornt[2+cf] < 0 ? -1 : 1;
5746: coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* K */
5747: orntNew[3] = o*of < 0 ? 0 : -1;
5748: coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* R */
5749: orntNew[4] = -1;
5750: cf = 0;
5751: of = ornt[2+cf] < 0 ? -1 : 1;
5752: coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* L */
5753: orntNew[5] = o*of < 0 ? 1 : -4;
5754: DMPlexSetCone(rdm, newp+1, coneNew);
5755: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5756: #if defined(PETSC_USE_DEBUG)
5757: 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);
5758: for (p = 0; p < 6; ++p) {
5759: 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);
5760: }
5761: #endif
5762: /* C hex */
5763: coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
5764: orntNew[0] = ornt[0] < 0 ? -4 : 2;
5765: coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* T */
5766: orntNew[1] = ornt[1] < 0 ? 0 : -2;
5767: cf = 2;
5768: of = ornt[2+cf] < 0 ? -1 : 1;
5769: coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* F */
5770: orntNew[2] = o*of < 0 ? 0 : -1;
5771: coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* K */
5772: orntNew[3] = 0;
5773: cf = 1;
5774: of = ornt[2+cf] < 0 ? -1 : 1;
5775: coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* R */
5776: orntNew[4] = o*of < 0 ? 0 : -1;
5777: coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* L */
5778: orntNew[5] = -4;
5779: DMPlexSetCone(rdm, newp+2, coneNew);
5780: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5781: #if defined(PETSC_USE_DEBUG)
5782: 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);
5783: for (p = 0; p < 6; ++p) {
5784: 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);
5785: }
5786: #endif
5787: }
5789: /* Split faces have 4 edges and the same cells as the parent */
5790: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
5791: PetscMalloc1(2 + maxSupportSize*2, &supportRef);
5792: for (f = fStart; f < fMax; ++f) {
5793: const PetscInt newp = fStartNew + (f - fStart)*3;
5794: const PetscInt *cone, *ornt, *support;
5795: PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s;
5797: DMPlexGetCone(dm, f, &cone);
5798: #if defined(PETSC_USE_DEBUG)
5799: for (p = 0; p < 3; ++p) {
5800: 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);
5801: }
5802: #endif
5803: DMPlexGetConeOrientation(dm, f, &ornt);
5804: /* A quad */
5805: coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
5806: orntNew[0] = ornt[2];
5807: coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
5808: orntNew[1] = ornt[0];
5809: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
5810: orntNew[2] = 0;
5811: coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
5812: orntNew[3] = -2;
5813: DMPlexSetCone(rdm, newp+0, coneNew);
5814: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
5815: #if defined(PETSC_USE_DEBUG)
5816: 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);
5817: for (p = 0; p < 4; ++p) {
5818: 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);
5819: }
5820: #endif
5821: /* B quad */
5822: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
5823: orntNew[0] = ornt[0];
5824: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
5825: orntNew[1] = ornt[1];
5826: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
5827: orntNew[2] = 0;
5828: coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
5829: orntNew[3] = -2;
5830: DMPlexSetCone(rdm, newp+1, coneNew);
5831: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
5832: #if defined(PETSC_USE_DEBUG)
5833: 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);
5834: for (p = 0; p < 4; ++p) {
5835: 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);
5836: }
5837: #endif
5838: /* C quad */
5839: coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
5840: orntNew[0] = ornt[1];
5841: coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
5842: orntNew[1] = ornt[2];
5843: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
5844: orntNew[2] = 0;
5845: coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
5846: orntNew[3] = -2;
5847: DMPlexSetCone(rdm, newp+2, coneNew);
5848: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
5849: #if defined(PETSC_USE_DEBUG)
5850: 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);
5851: for (p = 0; p < 4; ++p) {
5852: 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);
5853: }
5854: #endif
5855: DMPlexGetSupportSize(dm, f, &supportSize);
5856: DMPlexGetSupport(dm, f, &support);
5857: for (r = 0; r < 3; ++r) {
5858: for (s = 0; s < supportSize; ++s) {
5859: PetscInt subf;
5861: DMPlexGetConeSize(dm, support[s], &coneSize);
5862: 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);
5863: 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);
5864: DMPlexGetCone(dm, support[s], &cone);
5865: DMPlexGetConeOrientation(dm, support[s], &ornt);
5866: for (c = 0; c < coneSize; ++c) {
5867: if (cone[c] == f) break;
5868: }
5869: subf = GetTriSubfaceInverse_Static(ornt[c], r);
5870: if (coneSize == 4) {
5871: supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf];
5872: } else if (coneSize == 5) {
5873: 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);
5874: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + subf;
5875: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax);
5876: }
5877: DMPlexSetSupport(rdm, newp+r, supportRef);
5878: #if defined(PETSC_USE_DEBUG)
5879: 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);
5880: for (p = 0; p < supportSize; ++p) {
5881: 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);
5882: }
5883: #endif
5884: }
5885: }
5886: /* Interior faces have 4 edges and 2 cells */
5887: for (c = cStart; c < cMax; ++c) {
5888: PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6;
5889: const PetscInt *cone, *ornt;
5890: PetscInt coneNew[4], orntNew[4];
5891: PetscInt supportNew[2];
5893: DMPlexGetCone(dm, c, &cone);
5894: #if defined(PETSC_USE_DEBUG)
5895: for (p = 0; p < 4; ++p) {
5896: 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);
5897: }
5898: #endif
5899: DMPlexGetConeOrientation(dm, c, &ornt);
5900: /* Face {a, g, m, h} */
5901: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
5902: orntNew[0] = 0;
5903: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
5904: orntNew[1] = 0;
5905: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
5906: orntNew[2] = -2;
5907: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
5908: orntNew[3] = -2;
5909: DMPlexSetCone(rdm, newp, coneNew);
5910: DMPlexSetConeOrientation(rdm, newp, orntNew);
5911: #if defined(PETSC_USE_DEBUG)
5912: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5913: for (p = 0; p < 4; ++p) {
5914: 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);
5915: }
5916: #endif
5917: supportNew[0] = cStartNew + (c - cStart)*4 + 0;
5918: supportNew[1] = cStartNew + (c - cStart)*4 + 1;
5919: DMPlexSetSupport(rdm, newp, supportNew);
5920: #if defined(PETSC_USE_DEBUG)
5921: for (p = 0; p < 2; ++p) {
5922: 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);
5923: }
5924: #endif
5925: ++newp;
5926: /* Face {g, b, l , m} */
5927: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
5928: orntNew[0] = -2;
5929: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0);
5930: orntNew[1] = 0;
5931: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
5932: orntNew[2] = 0;
5933: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
5934: orntNew[3] = -2;
5935: DMPlexSetCone(rdm, newp, coneNew);
5936: DMPlexSetConeOrientation(rdm, newp, orntNew);
5937: #if defined(PETSC_USE_DEBUG)
5938: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5939: for (p = 0; p < 4; ++p) {
5940: 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);
5941: }
5942: #endif
5943: supportNew[0] = cStartNew + (c - cStart)*4 + 1;
5944: supportNew[1] = cStartNew + (c - cStart)*4 + 2;
5945: DMPlexSetSupport(rdm, newp, supportNew);
5946: #if defined(PETSC_USE_DEBUG)
5947: for (p = 0; p < 2; ++p) {
5948: 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);
5949: }
5950: #endif
5951: ++newp;
5952: /* Face {c, g, m, i} */
5953: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
5954: orntNew[0] = 0;
5955: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
5956: orntNew[1] = 0;
5957: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
5958: orntNew[2] = -2;
5959: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0);
5960: orntNew[3] = -2;
5961: DMPlexSetCone(rdm, newp, coneNew);
5962: DMPlexSetConeOrientation(rdm, newp, orntNew);
5963: #if defined(PETSC_USE_DEBUG)
5964: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5965: for (p = 0; p < 4; ++p) {
5966: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew);
5967: }
5968: #endif
5969: supportNew[0] = cStartNew + (c - cStart)*4 + 0;
5970: supportNew[1] = cStartNew + (c - cStart)*4 + 2;
5971: DMPlexSetSupport(rdm, newp, supportNew);
5972: #if defined(PETSC_USE_DEBUG)
5973: for (p = 0; p < 2; ++p) {
5974: 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);
5975: }
5976: #endif
5977: ++newp;
5978: /* Face {d, h, m, i} */
5979: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
5980: orntNew[0] = 0;
5981: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
5982: orntNew[1] = 0;
5983: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
5984: orntNew[2] = -2;
5985: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2);
5986: orntNew[3] = -2;
5987: DMPlexSetCone(rdm, newp, coneNew);
5988: DMPlexSetConeOrientation(rdm, newp, orntNew);
5989: #if defined(PETSC_USE_DEBUG)
5990: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
5991: for (p = 0; p < 4; ++p) {
5992: 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);
5993: }
5994: #endif
5995: supportNew[0] = cStartNew + (c - cStart)*4 + 0;
5996: supportNew[1] = cStartNew + (c - cStart)*4 + 3;
5997: DMPlexSetSupport(rdm, newp, supportNew);
5998: #if defined(PETSC_USE_DEBUG)
5999: for (p = 0; p < 2; ++p) {
6000: 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);
6001: }
6002: #endif
6003: ++newp;
6004: /* Face {h, m, l, e} */
6005: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
6006: orntNew[0] = 0;
6007: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
6008: orntNew[1] = -2;
6009: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1);
6010: orntNew[2] = -2;
6011: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
6012: orntNew[3] = 0;
6013: DMPlexSetCone(rdm, newp, coneNew);
6014: DMPlexSetConeOrientation(rdm, newp, orntNew);
6015: #if defined(PETSC_USE_DEBUG)
6016: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6017: for (p = 0; p < 4; ++p) {
6018: 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);
6019: }
6020: #endif
6021: supportNew[0] = cStartNew + (c - cStart)*4 + 1;
6022: supportNew[1] = cStartNew + (c - cStart)*4 + 3;
6023: DMPlexSetSupport(rdm, newp, supportNew);
6024: #if defined(PETSC_USE_DEBUG)
6025: for (p = 0; p < 2; ++p) {
6026: 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);
6027: }
6028: #endif
6029: ++newp;
6030: /* Face {i, m, l, f} */
6031: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
6032: orntNew[0] = 0;
6033: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
6034: orntNew[1] = -2;
6035: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2);
6036: orntNew[2] = -2;
6037: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1);
6038: orntNew[3] = 0;
6039: DMPlexSetCone(rdm, newp, coneNew);
6040: DMPlexSetConeOrientation(rdm, newp, orntNew);
6041: #if defined(PETSC_USE_DEBUG)
6042: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6043: for (p = 0; p < 4; ++p) {
6044: 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);
6045: }
6046: #endif
6047: supportNew[0] = cStartNew + (c - cStart)*4 + 2;
6048: supportNew[1] = cStartNew + (c - cStart)*4 + 3;
6049: DMPlexSetSupport(rdm, newp, supportNew);
6050: #if defined(PETSC_USE_DEBUG)
6051: for (p = 0; p < 2; ++p) {
6052: 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);
6053: }
6054: #endif
6055: ++newp;
6056: }
6057: /* Hybrid split faces have 4 edges and same cells */
6058: for (f = fMax; f < fEnd; ++f) {
6059: const PetscInt *cone, *ornt, *support;
6060: PetscInt coneNew[4], orntNew[4];
6061: PetscInt size, s;
6062: const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2;
6064: DMPlexGetCone(dm, f, &cone);
6065: #if defined(PETSC_USE_DEBUG)
6066: 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);
6067: 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);
6068: 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);
6069: 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);
6070: #endif
6071: DMPlexGetConeOrientation(dm, f, &ornt);
6072: /* A face */
6073: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
6074: orntNew[0] = ornt[0];
6075: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax);
6076: orntNew[1] = 0;
6077: coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
6078: orntNew[2] = ornt[1] < 0 ? 0 : -2;
6079: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[2] - eMax);
6080: orntNew[3] = ornt[2] < 0 ? 0 : -2;
6081: DMPlexSetCone(rdm, newp, coneNew);
6082: DMPlexSetConeOrientation(rdm, newp, orntNew);
6083: #if defined(PETSC_USE_DEBUG)
6084: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6085: for (p = 0; p < 4; ++p) {
6086: 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);
6087: }
6088: #endif
6090: /* B face */
6091: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
6092: orntNew[0] = ornt[0];
6093: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[3] - eMax);
6094: orntNew[1] = ornt[3];
6095: coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
6096: orntNew[2] = ornt[1] < 0 ? 0 : -2;
6097: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax);
6098: orntNew[3] = -2;
6099: DMPlexSetCone(rdm, newp+1, coneNew);
6100: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
6101: #if defined(PETSC_USE_DEBUG)
6102: 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);
6103: for (p = 0; p < 4; ++p) {
6104: 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);
6105: }
6106: #endif
6108: DMPlexGetSupportSize(dm, f, &size);
6109: DMPlexGetSupport(dm, f, &support);
6110: for (r = 0; r < 2; ++r) {
6111: for (s = 0; s < size; ++s) {
6112: const PetscInt *coneCell, *orntCell;
6113: PetscInt coneSize, o, of, c;
6115: DMPlexGetConeSize(dm, support[s], &coneSize);
6116: 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);
6117: DMPlexGetCone(dm, support[s], &coneCell);
6118: DMPlexGetConeOrientation(dm, support[s], &orntCell);
6119: o = orntCell[0] < 0 ? -1 : 1;
6120: o = 1;
6121: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
6122: 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);
6123: if (c == coneSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]);
6124: of = orntCell[c] < 0 ? -1 : 1;
6125: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + (c-2 + (o*of < 0 ? 1-r : r))%3;
6126: }
6127: DMPlexSetSupport(rdm, newp + r, supportRef);
6128: #if defined(PETSC_USE_DEBUG)
6129: for (p = 0; p < size; ++p) {
6130: 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);
6131: }
6132: #endif
6133: }
6134: }
6135: /* Interior hybrid faces have 4 edges and 2 cells */
6136: for (c = cMax; c < cEnd; ++c) {
6137: PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3;
6138: const PetscInt *cone, *ornt;
6139: PetscInt coneNew[4], orntNew[4];
6140: PetscInt supportNew[2];
6142: DMPlexGetCone(dm, c, &cone);
6143: #if defined(PETSC_USE_DEBUG)
6144: 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);
6145: 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);
6146: 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);
6147: 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);
6148: 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);
6149: #endif
6150: DMPlexGetConeOrientation(dm, c, &ornt);
6151: /* Face {a, g, h, d} */
6152: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
6153: orntNew[0] = 0;
6154: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6155: orntNew[1] = 0;
6156: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
6157: orntNew[2] = -2;
6158: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[2] - fMax);
6159: orntNew[3] = -2;
6160: DMPlexSetCone(rdm, newp, coneNew);
6161: DMPlexSetConeOrientation(rdm, newp, orntNew);
6162: #if defined(PETSC_USE_DEBUG)
6163: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6164: for (p = 0; p < 4; ++p) {
6165: 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);
6166: }
6167: #endif
6168: supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0;
6169: supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1;
6170: DMPlexSetSupport(rdm, newp, supportNew);
6171: #if defined(PETSC_USE_DEBUG)
6172: for (p = 0; p < 2; ++p) {
6173: 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);
6174: }
6175: #endif
6176: ++newp;
6177: /* Face {b, g, h, l} */
6178: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
6179: orntNew[0] = 0;
6180: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6181: orntNew[1] = 0;
6182: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
6183: orntNew[2] = -2;
6184: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[3] - fMax);
6185: orntNew[3] = -2;
6186: DMPlexSetCone(rdm, newp, coneNew);
6187: DMPlexSetConeOrientation(rdm, newp, orntNew);
6188: #if defined(PETSC_USE_DEBUG)
6189: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6190: for (p = 0; p < 4; ++p) {
6191: 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);
6192: }
6193: #endif
6194: supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1;
6195: supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2;
6196: DMPlexSetSupport(rdm, newp, supportNew);
6197: #if defined(PETSC_USE_DEBUG)
6198: for (p = 0; p < 2; ++p) {
6199: 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);
6200: }
6201: #endif
6202: ++newp;
6203: /* Face {c, g, h, f} */
6204: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
6205: orntNew[0] = 0;
6206: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6207: orntNew[1] = 0;
6208: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
6209: orntNew[2] = -2;
6210: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[4] - fMax);
6211: orntNew[3] = -2;
6212: DMPlexSetCone(rdm, newp, coneNew);
6213: DMPlexSetConeOrientation(rdm, newp, orntNew);
6214: #if defined(PETSC_USE_DEBUG)
6215: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6216: for (p = 0; p < 4; ++p) {
6217: 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);
6218: }
6219: #endif
6220: supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2;
6221: supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0;
6222: DMPlexSetSupport(rdm, newp, supportNew);
6223: #if defined(PETSC_USE_DEBUG)
6224: for (p = 0; p < 2; ++p) {
6225: 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);
6226: }
6227: #endif
6228: }
6229: /* Face edges have 2 vertices and 2 + cell faces supports */
6230: for (f = fStart; f < fMax; ++f) {
6231: const PetscInt *cone, *ornt, *support;
6232: PetscInt coneSize, supportSize, s;
6234: DMPlexGetSupportSize(dm, f, &supportSize);
6235: DMPlexGetSupport(dm, f, &support);
6236: for (r = 0; r < 3; ++r) {
6237: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
6238: PetscInt coneNew[2];
6239: PetscInt fint[4][3] = { {0, 1, 2},
6240: {3, 4, 0},
6241: {2, 5, 3},
6242: {1, 4, 5} };
6244: DMPlexGetCone(dm, f, &cone);
6245: 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);
6246: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
6247: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart;
6248: DMPlexSetCone(rdm, newp, coneNew);
6249: #if defined(PETSC_USE_DEBUG)
6250: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6251: for (p = 0; p < 2; ++p) {
6252: 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);
6253: }
6254: #endif
6255: supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3;
6256: supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3;
6257: for (s = 0; s < supportSize; ++s) {
6258: PetscInt er;
6260: supportRef[2+s] = -1;
6261: DMPlexGetConeSize(dm, support[s], &coneSize);
6262: 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);
6263: 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);
6264: DMPlexGetCone(dm, support[s], &cone);
6265: DMPlexGetConeOrientation(dm, support[s], &ornt);
6266: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
6267: er = GetTriInteriorEdgeInverse_Static(ornt[c], r);
6268: if (coneSize == 4) {
6269: supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (support[s] - cStart)*6 + fint[c][er];
6270: } else if (coneSize == 5) {
6271: 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);
6272: supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + er;
6273: }
6274: }
6275: DMPlexSetSupport(rdm, newp, supportRef);
6276: #if defined(PETSC_USE_DEBUG)
6277: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6278: for (p = 0; p < supportSize + 2; ++p) {
6279: 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);
6280: }
6281: #endif
6282: }
6283: }
6284: /* Interior cell edges have 2 vertices and 3 faces */
6285: for (c = cStart; c < cMax; ++c) {
6286: const PetscInt *cone;
6287: PetscInt fint[4][3] = { {0,1,2},
6288: {0,3,4},
6289: {2,3,5},
6290: {1,4,5} } ;
6292: DMPlexGetCone(dm, c, &cone);
6293: for (r = 0; r < 4; r++) {
6294: PetscInt coneNew[2], supportNew[3];
6295: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r;
6297: 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);
6298: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
6299: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax -fStart) + c - cStart;
6300: DMPlexSetCone(rdm, newp, coneNew);
6301: #if defined(PETSC_USE_DEBUG)
6302: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6303: for (p = 0; p < 2; ++p) {
6304: 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);
6305: }
6306: #endif
6307: supportNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][0];
6308: supportNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][1];
6309: supportNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][2];
6310: DMPlexSetSupport(rdm, newp, supportNew);
6311: #if defined(PETSC_USE_DEBUG)
6312: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6313: for (p = 0; p < 3; ++p) {
6314: 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);
6315: }
6316: #endif
6317: }
6318: }
6319: /* Hybrid edges have two vertices and the same faces */
6320: for (e = eMax; e < eEnd; ++e) {
6321: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax);
6322: const PetscInt *cone, *support, *fcone;
6323: PetscInt coneNew[2], size, fsize, s;
6325: DMPlexGetCone(dm, e, &cone);
6326: DMPlexGetSupportSize(dm, e, &size);
6327: DMPlexGetSupport(dm, e, &support);
6328: coneNew[0] = vStartNew + (cone[0] - vStart);
6329: coneNew[1] = vStartNew + (cone[1] - vStart);
6330: DMPlexSetCone(rdm, newp, coneNew);
6331: #if defined(PETSC_USE_DEBUG)
6332: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is a edge [%D, %D)", newp, eStartNew, eEndNew);
6333: for (p = 0; p < 2; ++p) {
6334: 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);
6335: }
6336: #endif
6337: for (s = 0; s < size; ++s) {
6338: DMPlexGetConeSize(dm, support[s], &fsize);
6339: DMPlexGetCone(dm, support[s], &fcone);
6340: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
6341: if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]);
6342: supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + c-2;
6343: }
6344: DMPlexSetSupport(rdm, newp, supportRef);
6345: #if defined(PETSC_USE_DEBUG)
6346: for (p = 0; p < size; ++p) {
6347: 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);
6348: }
6349: #endif
6350: }
6351: /* Hybrid face edges have 2 vertices and 2 + cell faces supports */
6352: for (f = fMax; f < fEnd; ++f) {
6353: const PetscInt *cone, *ornt, *support;
6354: PetscInt coneSize, supportSize;
6355: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + f - fMax;
6356: PetscInt coneNew[2], s;
6358: DMPlexGetCone(dm, f, &cone);
6359: #if defined(PETSC_USE_DEBUG)
6360: 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);
6361: 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);
6362: #endif
6363: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
6364: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
6365: DMPlexSetCone(rdm, newp, coneNew);
6366: #if defined(PETSC_USE_DEBUG)
6367: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6368: for (p = 0; p < 2; ++p) {
6369: 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);
6370: }
6371: #endif
6372: supportRef[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 0;
6373: supportRef[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 1;
6374: DMPlexGetSupportSize(dm, f, &supportSize);
6375: DMPlexGetSupport(dm, f, &support);
6376: for (s = 0; s < supportSize; ++s) {
6377: DMPlexGetConeSize(dm, support[s], &coneSize);
6378: 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);
6379: DMPlexGetCone(dm, support[s], &cone);
6380: DMPlexGetConeOrientation(dm, support[s], &ornt);
6381: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
6382: 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);
6383: supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c - 2;
6384: }
6385: DMPlexSetSupport(rdm, newp, supportRef);
6386: #if defined(PETSC_USE_DEBUG)
6387: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6388: for (p = 0; p < supportSize + 2; ++p) {
6389: 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);
6390: }
6391: #endif
6392: }
6393: /* Hybrid cell edges have 2 vertices and 3 faces */
6394: for (c = cMax; c < cEnd; ++c) {
6395: PetscInt coneNew[2], supportNew[3];
6396: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax;
6397: const PetscInt *cone;
6399: DMPlexGetCone(dm, c, &cone);
6400: #if defined(PETSC_USE_DEBUG)
6401: 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);
6402: 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);
6403: #endif
6404: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
6405: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
6406: DMPlexSetCone(rdm, newp, coneNew);
6407: #if defined(PETSC_USE_DEBUG)
6408: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6409: for (p = 0; p < 2; ++p) {
6410: 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);
6411: }
6412: #endif
6413: supportNew[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
6414: supportNew[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
6415: supportNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
6416: DMPlexSetSupport(rdm, newp, supportNew);
6417: #if defined(PETSC_USE_DEBUG)
6418: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6419: for (p = 0; p < 3; ++p) {
6420: 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);
6421: }
6422: #endif
6423: }
6424: /* Old vertices have identical supports */
6425: for (v = vStart; v < vEnd; ++v) {
6426: const PetscInt newp = vStartNew + (v - vStart);
6427: const PetscInt *support, *cone;
6428: PetscInt size, s;
6430: DMPlexGetSupportSize(dm, v, &size);
6431: DMPlexGetSupport(dm, v, &support);
6432: for (s = 0; s < size; ++s) {
6433: const PetscInt e = support[s];
6435: supportRef[s] = -1;
6436: if (eStart <= e) {
6437: if (e < eMax) {
6438: DMPlexGetCone(dm, e, &cone);
6439: supportRef[s] = eStartNew + (e - eStart)*2 + (cone[1] == v ? 1 : 0);
6440: } else if (e < eEnd) {
6441: supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + e - eMax;
6442: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd);
6443: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd);
6444: }
6445: DMPlexSetSupport(rdm, newp, supportRef);
6446: #if defined(PETSC_USE_DEBUG)
6447: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6448: for (p = 0; p < size; ++p) {
6449: 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);
6450: }
6451: #endif
6452: }
6453: /* Interior edge vertices have 2 + faces supports */
6454: for (e = eStart; e < eMax; ++e) {
6455: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
6456: const PetscInt *cone, *support;
6457: PetscInt size, s;
6459: DMPlexGetSupportSize(dm, e, &size);
6460: DMPlexGetSupport(dm, e, &support);
6461: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
6462: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
6463: for (s = 0; s < size; ++s) {
6464: PetscInt r, coneSize;
6466: supportRef[2+s] = -1;
6467: DMPlexGetConeSize(dm, support[s], &coneSize);
6468: 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);
6469: 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);
6470: DMPlexGetCone(dm, support[s], &cone);
6471: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
6472: if (coneSize == 3) supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + r;
6473: else if (coneSize == 4) {
6474: 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);
6475: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + support[s] - fMax;
6476: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax);
6477: }
6478: DMPlexSetSupport(rdm, newp, supportRef);
6479: #if defined(PETSC_USE_DEBUG)
6480: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6481: for (p = 0; p < 2+size; ++p) {
6482: 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);
6483: }
6484: #endif
6485: }
6486: /* Split Edges have 2 vertices and the same faces as the parent */
6487: for (e = eStart; e < eMax; ++e) {
6488: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
6490: for (r = 0; r < 2; ++r) {
6491: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
6492: const PetscInt *cone, *ornt, *support;
6493: PetscInt coneNew[2], coneSize, c, supportSize, s;
6495: DMPlexGetCone(dm, e, &cone);
6496: coneNew[0] = vStartNew + (cone[0] - vStart);
6497: coneNew[1] = vStartNew + (cone[1] - vStart);
6498: coneNew[(r+1)%2] = newv;
6499: DMPlexSetCone(rdm, newp, coneNew);
6500: #if defined(PETSC_USE_DEBUG)
6501: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6502: for (p = 0; p < 2; ++p) {
6503: 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);
6504: }
6505: #endif
6506: DMPlexGetSupportSize(dm, e, &supportSize);
6507: DMPlexGetSupport(dm, e, &support);
6508: for (s = 0; s < supportSize; ++s) {
6509: DMPlexGetConeSize(dm, support[s], &coneSize);
6510: 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);
6511: 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);
6512: DMPlexGetCone(dm, support[s], &cone);
6513: DMPlexGetConeOrientation(dm, support[s], &ornt);
6514: for (c = 0; c < coneSize; ++c) {
6515: if (cone[c] == e) break;
6516: }
6517: if (coneSize == 3) supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3;
6518: else if (coneSize == 4) {
6519: 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);
6520: supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
6521: } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax);
6522: }
6523: DMPlexSetSupport(rdm, newp, supportRef);
6524: #if defined(PETSC_USE_DEBUG)
6525: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
6526: for (p = 0; p < supportSize; ++p) {
6527: 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);
6528: }
6529: #endif
6530: }
6531: }
6532: /* Face vertices have 3 + cells supports */
6533: for (f = fStart; f < fMax; ++f) {
6534: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
6535: const PetscInt *cone, *support;
6536: PetscInt size, s;
6538: DMPlexGetSupportSize(dm, f, &size);
6539: DMPlexGetSupport(dm, f, &support);
6540: supportRef[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
6541: supportRef[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
6542: supportRef[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
6543: for (s = 0; s < size; ++s) {
6544: PetscInt r, coneSize;
6546: supportRef[3+s] = -1;
6547: DMPlexGetConeSize(dm, support[s], &coneSize);
6548: 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);
6549: 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);
6550: DMPlexGetCone(dm, support[s], &cone);
6551: for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;}
6552: if (coneSize == 4) supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (support[s] - cStart)*4 + r;
6553: else if (coneSize == 5) {
6554: 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);
6555: supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + support[s] - cMax;
6556: }
6557: }
6558: DMPlexSetSupport(rdm, newp, supportRef);
6559: #if defined(PETSC_USE_DEBUG)
6560: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6561: for (p = 0; p < 3+size; ++p) {
6562: 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);
6563: }
6564: #endif
6565: }
6566: /* Interior cell vertices have 4 supports */
6567: for (c = cStart; c < cMax; ++c) {
6568: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart;
6570: supportRef[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0;
6571: supportRef[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1;
6572: supportRef[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2;
6573: supportRef[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3;
6574: DMPlexSetSupport(rdm, newp, supportRef);
6575: #if defined(PETSC_USE_DEBUG)
6576: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
6577: for (p = 0; p < 4; ++p) {
6578: 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);
6579: }
6580: #endif
6581: }
6582: PetscFree(supportRef);
6583: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
6584: break;
6585: case REFINER_HEX_3D:
6586: /*
6587: Bottom (viewed from top) Top
6588: 1---------2---------2 7---------2---------6
6589: | | | | | |
6590: | B 2 C | | H 2 G |
6591: | | | | | |
6592: 3----3----0----1----1 3----3----0----1----1
6593: | | | | | |
6594: | A 0 D | | E 0 F |
6595: | | | | | |
6596: 0---------0---------3 4---------0---------5
6597: */
6598: /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
6599: for (c = cStart; c < cEnd; ++c) {
6600: const PetscInt newp = (c - cStart)*8;
6601: const PetscInt *cone, *ornt;
6602: PetscInt coneNew[6], orntNew[6];
6604: DMPlexGetCone(dm, c, &cone);
6605: DMPlexGetConeOrientation(dm, c, &ornt);
6606: /* A hex */
6607: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
6608: orntNew[0] = ornt[0];
6609: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */
6610: orntNew[1] = 0;
6611: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
6612: orntNew[2] = ornt[2];
6613: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */
6614: orntNew[3] = 0;
6615: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */
6616: orntNew[4] = 0;
6617: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
6618: orntNew[5] = ornt[5];
6619: DMPlexSetCone(rdm, newp+0, coneNew);
6620: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
6621: #if defined(PETSC_USE_DEBUG)
6622: 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);
6623: for (p = 0; p < 6; ++p) {
6624: 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);
6625: }
6626: #endif
6627: /* B hex */
6628: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
6629: orntNew[0] = ornt[0];
6630: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */
6631: orntNew[1] = 0;
6632: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */
6633: orntNew[2] = -1;
6634: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
6635: orntNew[3] = ornt[3];
6636: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */
6637: orntNew[4] = 0;
6638: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
6639: orntNew[5] = ornt[5];
6640: DMPlexSetCone(rdm, newp+1, coneNew);
6641: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
6642: #if defined(PETSC_USE_DEBUG)
6643: 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);
6644: for (p = 0; p < 6; ++p) {
6645: 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);
6646: }
6647: #endif
6648: /* C hex */
6649: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
6650: orntNew[0] = ornt[0];
6651: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */
6652: orntNew[1] = 0;
6653: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */
6654: orntNew[2] = -1;
6655: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
6656: orntNew[3] = ornt[3];
6657: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
6658: orntNew[4] = ornt[4];
6659: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */
6660: orntNew[5] = -4;
6661: DMPlexSetCone(rdm, newp+2, coneNew);
6662: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
6663: #if defined(PETSC_USE_DEBUG)
6664: 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);
6665: for (p = 0; p < 6; ++p) {
6666: 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);
6667: }
6668: #endif
6669: /* D hex */
6670: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
6671: orntNew[0] = ornt[0];
6672: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */
6673: orntNew[1] = 0;
6674: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
6675: orntNew[2] = ornt[2];
6676: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */
6677: orntNew[3] = 0;
6678: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
6679: orntNew[4] = ornt[4];
6680: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */
6681: orntNew[5] = -4;
6682: DMPlexSetCone(rdm, newp+3, coneNew);
6683: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
6684: #if defined(PETSC_USE_DEBUG)
6685: 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);
6686: for (p = 0; p < 6; ++p) {
6687: 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);
6688: }
6689: #endif
6690: /* E hex */
6691: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */
6692: orntNew[0] = -4;
6693: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
6694: orntNew[1] = ornt[1];
6695: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
6696: orntNew[2] = ornt[2];
6697: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */
6698: orntNew[3] = 0;
6699: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */
6700: orntNew[4] = -1;
6701: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
6702: orntNew[5] = ornt[5];
6703: DMPlexSetCone(rdm, newp+4, coneNew);
6704: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
6705: #if defined(PETSC_USE_DEBUG)
6706: 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);
6707: for (p = 0; p < 6; ++p) {
6708: 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);
6709: }
6710: #endif
6711: /* F hex */
6712: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */
6713: orntNew[0] = -4;
6714: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
6715: orntNew[1] = ornt[1];
6716: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
6717: orntNew[2] = ornt[2];
6718: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */
6719: orntNew[3] = -1;
6720: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
6721: orntNew[4] = ornt[4];
6722: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */
6723: orntNew[5] = 1;
6724: DMPlexSetCone(rdm, newp+5, coneNew);
6725: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
6726: #if defined(PETSC_USE_DEBUG)
6727: 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);
6728: for (p = 0; p < 6; ++p) {
6729: 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);
6730: }
6731: #endif
6732: /* G hex */
6733: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */
6734: orntNew[0] = -4;
6735: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
6736: orntNew[1] = ornt[1];
6737: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */
6738: orntNew[2] = 0;
6739: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
6740: orntNew[3] = ornt[3];
6741: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
6742: orntNew[4] = ornt[4];
6743: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */
6744: orntNew[5] = -3;
6745: DMPlexSetCone(rdm, newp+6, coneNew);
6746: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
6747: #if defined(PETSC_USE_DEBUG)
6748: 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);
6749: for (p = 0; p < 6; ++p) {
6750: 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);
6751: }
6752: #endif
6753: /* H hex */
6754: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */
6755: orntNew[0] = -4;
6756: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
6757: orntNew[1] = ornt[1];
6758: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */
6759: orntNew[2] = -1;
6760: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
6761: orntNew[3] = ornt[3];
6762: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */
6763: orntNew[4] = 3;
6764: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
6765: orntNew[5] = ornt[5];
6766: DMPlexSetCone(rdm, newp+7, coneNew);
6767: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
6768: #if defined(PETSC_USE_DEBUG)
6769: 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);
6770: for (p = 0; p < 6; ++p) {
6771: 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);
6772: }
6773: #endif
6774: }
6775: /* Split faces have 4 edges and the same cells as the parent */
6776: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
6777: PetscMalloc1(4 + maxSupportSize*2, &supportRef);
6778: for (f = fStart; f < fEnd; ++f) {
6779: for (r = 0; r < 4; ++r) {
6780: /* TODO: This can come from GetFaces_Internal() */
6781: 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};
6782: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
6783: const PetscInt *cone, *ornt, *support;
6784: PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s;
6786: DMPlexGetCone(dm, f, &cone);
6787: DMPlexGetConeOrientation(dm, f, &ornt);
6788: coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
6789: orntNew[(r+3)%4] = ornt[(r+3)%4];
6790: coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
6791: orntNew[(r+0)%4] = ornt[r];
6792: coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
6793: orntNew[(r+1)%4] = 0;
6794: coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
6795: orntNew[(r+2)%4] = -2;
6796: DMPlexSetCone(rdm, newp, coneNew);
6797: DMPlexSetConeOrientation(rdm, newp, orntNew);
6798: #if defined(PETSC_USE_DEBUG)
6799: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6800: for (p = 0; p < 4; ++p) {
6801: 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);
6802: }
6803: #endif
6804: DMPlexGetSupportSize(dm, f, &supportSize);
6805: DMPlexGetSupport(dm, f, &support);
6806: for (s = 0; s < supportSize; ++s) {
6807: DMPlexGetConeSize(dm, support[s], &coneSize);
6808: DMPlexGetCone(dm, support[s], &cone);
6809: DMPlexGetConeOrientation(dm, support[s], &ornt);
6810: for (c = 0; c < coneSize; ++c) {
6811: if (cone[c] == f) break;
6812: }
6813: supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
6814: }
6815: DMPlexSetSupport(rdm, newp, supportRef);
6816: #if defined(PETSC_USE_DEBUG)
6817: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6818: for (p = 0; p < supportSize; ++p) {
6819: 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);
6820: }
6821: #endif
6822: }
6823: }
6824: /* Interior faces have 4 edges and 2 cells */
6825: for (c = cStart; c < cEnd; ++c) {
6826: 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};
6827: const PetscInt *cone, *ornt;
6828: PetscInt newp, coneNew[4], orntNew[4], supportNew[2];
6830: DMPlexGetCone(dm, c, &cone);
6831: DMPlexGetConeOrientation(dm, c, &ornt);
6832: /* A-D face */
6833: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
6834: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
6835: orntNew[0] = 0;
6836: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6837: orntNew[1] = 0;
6838: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
6839: orntNew[2] = -2;
6840: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
6841: orntNew[3] = -2;
6842: DMPlexSetCone(rdm, newp, coneNew);
6843: DMPlexSetConeOrientation(rdm, newp, orntNew);
6844: #if defined(PETSC_USE_DEBUG)
6845: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6846: for (p = 0; p < 4; ++p) {
6847: 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);
6848: }
6849: #endif
6850: /* C-D face */
6851: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
6852: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
6853: orntNew[0] = 0;
6854: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6855: orntNew[1] = 0;
6856: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
6857: orntNew[2] = -2;
6858: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
6859: orntNew[3] = -2;
6860: DMPlexSetCone(rdm, newp, coneNew);
6861: DMPlexSetConeOrientation(rdm, newp, orntNew);
6862: #if defined(PETSC_USE_DEBUG)
6863: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6864: for (p = 0; p < 4; ++p) {
6865: 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);
6866: }
6867: #endif
6868: /* B-C face */
6869: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
6870: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
6871: orntNew[0] = -2;
6872: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
6873: orntNew[1] = 0;
6874: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
6875: orntNew[2] = 0;
6876: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6877: orntNew[3] = -2;
6878: DMPlexSetCone(rdm, newp, coneNew);
6879: DMPlexSetConeOrientation(rdm, newp, orntNew);
6880: #if defined(PETSC_USE_DEBUG)
6881: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6882: for (p = 0; p < 4; ++p) {
6883: 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);
6884: }
6885: #endif
6886: /* A-B face */
6887: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
6888: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
6889: orntNew[0] = -2;
6890: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
6891: orntNew[1] = 0;
6892: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
6893: orntNew[2] = 0;
6894: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
6895: orntNew[3] = -2;
6896: DMPlexSetCone(rdm, newp, coneNew);
6897: DMPlexSetConeOrientation(rdm, newp, orntNew);
6898: #if defined(PETSC_USE_DEBUG)
6899: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6900: for (p = 0; p < 4; ++p) {
6901: 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);
6902: }
6903: #endif
6904: /* E-F face */
6905: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
6906: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
6907: orntNew[0] = -2;
6908: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
6909: orntNew[1] = -2;
6910: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
6911: orntNew[2] = 0;
6912: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6913: orntNew[3] = 0;
6914: DMPlexSetCone(rdm, newp, coneNew);
6915: DMPlexSetConeOrientation(rdm, newp, orntNew);
6916: #if defined(PETSC_USE_DEBUG)
6917: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6918: for (p = 0; p < 4; ++p) {
6919: 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);
6920: }
6921: #endif
6922: /* F-G face */
6923: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
6924: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
6925: orntNew[0] = -2;
6926: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
6927: orntNew[1] = -2;
6928: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
6929: orntNew[2] = 0;
6930: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6931: orntNew[3] = 0;
6932: DMPlexSetCone(rdm, newp, coneNew);
6933: DMPlexSetConeOrientation(rdm, newp, orntNew);
6934: #if defined(PETSC_USE_DEBUG)
6935: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6936: for (p = 0; p < 4; ++p) {
6937: 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);
6938: }
6939: #endif
6940: /* G-H face */
6941: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
6942: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
6943: orntNew[0] = -2;
6944: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
6945: orntNew[1] = 0;
6946: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6947: orntNew[2] = 0;
6948: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
6949: orntNew[3] = -2;
6950: DMPlexSetCone(rdm, newp, coneNew);
6951: DMPlexSetConeOrientation(rdm, newp, orntNew);
6952: #if defined(PETSC_USE_DEBUG)
6953: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6954: for (p = 0; p < 4; ++p) {
6955: 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);
6956: }
6957: #endif
6958: /* E-H face */
6959: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
6960: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
6961: orntNew[0] = -2;
6962: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
6963: orntNew[1] = -2;
6964: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
6965: orntNew[2] = 0;
6966: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
6967: orntNew[3] = 0;
6968: DMPlexSetCone(rdm, newp, coneNew);
6969: DMPlexSetConeOrientation(rdm, newp, orntNew);
6970: #if defined(PETSC_USE_DEBUG)
6971: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6972: for (p = 0; p < 4; ++p) {
6973: 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);
6974: }
6975: #endif
6976: /* A-E face */
6977: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
6978: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
6979: orntNew[0] = 0;
6980: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
6981: orntNew[1] = 0;
6982: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
6983: orntNew[2] = -2;
6984: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
6985: orntNew[3] = -2;
6986: DMPlexSetCone(rdm, newp, coneNew);
6987: DMPlexSetConeOrientation(rdm, newp, orntNew);
6988: #if defined(PETSC_USE_DEBUG)
6989: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
6990: for (p = 0; p < 4; ++p) {
6991: 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);
6992: }
6993: #endif
6994: /* D-F face */
6995: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
6996: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
6997: orntNew[0] = -2;
6998: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
6999: orntNew[1] = 0;
7000: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
7001: orntNew[2] = 0;
7002: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
7003: orntNew[3] = -2;
7004: DMPlexSetCone(rdm, newp, coneNew);
7005: DMPlexSetConeOrientation(rdm, newp, orntNew);
7006: #if defined(PETSC_USE_DEBUG)
7007: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
7008: for (p = 0; p < 4; ++p) {
7009: 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);
7010: }
7011: #endif
7012: /* C-G face */
7013: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
7014: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
7015: orntNew[0] = -2;
7016: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
7017: orntNew[1] = -2;
7018: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
7019: orntNew[2] = 0;
7020: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
7021: orntNew[3] = 0;
7022: DMPlexSetCone(rdm, newp, coneNew);
7023: DMPlexSetConeOrientation(rdm, newp, orntNew);
7024: #if defined(PETSC_USE_DEBUG)
7025: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
7026: for (p = 0; p < 4; ++p) {
7027: 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);
7028: }
7029: #endif
7030: /* B-H face */
7031: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
7032: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
7033: orntNew[0] = 0;
7034: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
7035: orntNew[1] = -2;
7036: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
7037: orntNew[2] = -2;
7038: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
7039: orntNew[3] = 0;
7040: DMPlexSetCone(rdm, newp, coneNew);
7041: DMPlexSetConeOrientation(rdm, newp, orntNew);
7042: #if defined(PETSC_USE_DEBUG)
7043: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
7044: for (p = 0; p < 4; ++p) {
7045: 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);
7046: }
7047: #endif
7048: for (r = 0; r < 12; ++r) {
7049: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
7050: supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
7051: supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
7052: DMPlexSetSupport(rdm, newp, supportNew);
7053: #if defined(PETSC_USE_DEBUG)
7054: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew);
7055: for (p = 0; p < 2; ++p) {
7056: 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);
7057: }
7058: #endif
7059: }
7060: }
7061: /* Split edges have 2 vertices and the same faces as the parent */
7062: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
7063: for (e = eStart; e < eEnd; ++e) {
7064: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
7066: for (r = 0; r < 2; ++r) {
7067: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
7068: const PetscInt *cone, *ornt, *support;
7069: PetscInt coneNew[2], coneSize, c, supportSize, s;
7071: DMPlexGetCone(dm, e, &cone);
7072: coneNew[0] = vStartNew + (cone[0] - vStart);
7073: coneNew[1] = vStartNew + (cone[1] - vStart);
7074: coneNew[(r+1)%2] = newv;
7075: DMPlexSetCone(rdm, newp, coneNew);
7076: #if defined(PETSC_USE_DEBUG)
7077: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7078: for (p = 0; p < 2; ++p) {
7079: 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);
7080: }
7081: #endif
7082: DMPlexGetSupportSize(dm, e, &supportSize);
7083: DMPlexGetSupport(dm, e, &support);
7084: for (s = 0; s < supportSize; ++s) {
7085: DMPlexGetConeSize(dm, support[s], &coneSize);
7086: DMPlexGetCone(dm, support[s], &cone);
7087: DMPlexGetConeOrientation(dm, support[s], &ornt);
7088: for (c = 0; c < coneSize; ++c) {
7089: if (cone[c] == e) break;
7090: }
7091: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
7092: }
7093: DMPlexSetSupport(rdm, newp, supportRef);
7094: #if defined(PETSC_USE_DEBUG)
7095: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7096: for (p = 0; p < supportSize; ++p) {
7097: 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);
7098: }
7099: #endif
7100: }
7101: }
7102: /* Face edges have 2 vertices and 2+cells faces */
7103: for (f = fStart; f < fEnd; ++f) {
7104: 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};
7105: const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
7106: const PetscInt *cone, *coneCell, *orntCell, *support;
7107: PetscInt coneNew[2], coneSize, c, supportSize, s;
7109: DMPlexGetCone(dm, f, &cone);
7110: for (r = 0; r < 4; ++r) {
7111: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
7113: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
7114: coneNew[1] = newv;
7115: DMPlexSetCone(rdm, newp, coneNew);
7116: #if defined(PETSC_USE_DEBUG)
7117: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7118: for (p = 0; p < 2; ++p) {
7119: 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);
7120: }
7121: #endif
7122: DMPlexGetSupportSize(dm, f, &supportSize);
7123: DMPlexGetSupport(dm, f, &support);
7124: supportRef[0] = fStartNew + (f - fStart)*4 + r;
7125: supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
7126: for (s = 0; s < supportSize; ++s) {
7127: DMPlexGetConeSize(dm, support[s], &coneSize);
7128: DMPlexGetCone(dm, support[s], &coneCell);
7129: DMPlexGetConeOrientation(dm, support[s], &orntCell);
7130: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
7131: supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
7132: }
7133: DMPlexSetSupport(rdm, newp, supportRef);
7134: #if defined(PETSC_USE_DEBUG)
7135: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7136: for (p = 0; p < 2+supportSize; ++p) {
7137: 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);
7138: }
7139: #endif
7140: }
7141: }
7142: /* Cell edges have 2 vertices and 4 faces */
7143: for (c = cStart; c < cEnd; ++c) {
7144: 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};
7145: const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
7146: const PetscInt *cone;
7147: PetscInt coneNew[2], supportNew[4];
7149: DMPlexGetCone(dm, c, &cone);
7150: for (r = 0; r < 6; ++r) {
7151: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
7153: coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
7154: coneNew[1] = newv;
7155: DMPlexSetCone(rdm, newp, coneNew);
7156: #if defined(PETSC_USE_DEBUG)
7157: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7158: for (p = 0; p < 2; ++p) {
7159: 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);
7160: }
7161: #endif
7162: for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
7163: DMPlexSetSupport(rdm, newp, supportNew);
7164: #if defined(PETSC_USE_DEBUG)
7165: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew);
7166: for (p = 0; p < 4; ++p) {
7167: 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);
7168: }
7169: #endif
7170: }
7171: }
7172: /* Old vertices have identical supports */
7173: for (v = vStart; v < vEnd; ++v) {
7174: const PetscInt newp = vStartNew + (v - vStart);
7175: const PetscInt *support, *cone;
7176: PetscInt size, s;
7178: DMPlexGetSupportSize(dm, v, &size);
7179: DMPlexGetSupport(dm, v, &support);
7180: for (s = 0; s < size; ++s) {
7181: PetscInt r = 0;
7183: DMPlexGetCone(dm, support[s], &cone);
7184: if (cone[1] == v) r = 1;
7185: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
7186: }
7187: DMPlexSetSupport(rdm, newp, supportRef);
7188: #if defined(PETSC_USE_DEBUG)
7189: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
7190: for (p = 0; p < size; ++p) {
7191: 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);
7192: }
7193: #endif
7194: }
7195: /* Edge vertices have 2 + faces supports */
7196: for (e = eStart; e < eEnd; ++e) {
7197: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
7198: const PetscInt *cone, *support;
7199: PetscInt size, s;
7201: DMPlexGetSupportSize(dm, e, &size);
7202: DMPlexGetSupport(dm, e, &support);
7203: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
7204: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
7205: for (s = 0; s < size; ++s) {
7206: PetscInt r;
7208: DMPlexGetCone(dm, support[s], &cone);
7209: for (r = 0; r < 4; ++r) if (cone[r] == e) break;
7210: supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
7211: }
7212: DMPlexSetSupport(rdm, newp, supportRef);
7213: #if defined(PETSC_USE_DEBUG)
7214: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
7215: for (p = 0; p < 2+size; ++p) {
7216: 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);
7217: }
7218: #endif
7219: }
7220: /* Face vertices have 4 + cells supports */
7221: for (f = fStart; f < fEnd; ++f) {
7222: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
7223: const PetscInt *cone, *support;
7224: PetscInt size, s;
7226: DMPlexGetSupportSize(dm, f, &size);
7227: DMPlexGetSupport(dm, f, &support);
7228: for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
7229: for (s = 0; s < size; ++s) {
7230: PetscInt r;
7232: DMPlexGetCone(dm, support[s], &cone);
7233: for (r = 0; r < 6; ++r) if (cone[r] == f) break;
7234: supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
7235: }
7236: DMPlexSetSupport(rdm, newp, supportRef);
7237: #if defined(PETSC_USE_DEBUG)
7238: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
7239: for (p = 0; p < 4+size; ++p) {
7240: 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);
7241: }
7242: #endif
7243: }
7244: /* Cell vertices have 6 supports */
7245: for (c = cStart; c < cEnd; ++c) {
7246: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
7247: PetscInt supportNew[6];
7249: for (r = 0; r < 6; ++r) {
7250: supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
7251: }
7252: DMPlexSetSupport(rdm, newp, supportNew);
7253: }
7254: PetscFree(supportRef);
7255: break;
7256: case REFINER_HYBRID_HEX_3D:
7257: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);
7258: /*
7259: Bottom (viewed from top) Top
7260: 1---------2---------2 7---------2---------6
7261: | | | | | |
7262: | B 2 C | | H 2 G |
7263: | | | | | |
7264: 3----3----0----1----1 3----3----0----1----1
7265: | | | | | |
7266: | A 0 D | | E 0 F |
7267: | | | | | |
7268: 0---------0---------3 4---------0---------5
7269: */
7270: /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
7271: for (c = cStart; c < cMax; ++c) {
7272: const PetscInt newp = (c - cStart)*8;
7273: const PetscInt *cone, *ornt;
7274: PetscInt coneNew[6], orntNew[6];
7276: DMPlexGetCone(dm, c, &cone);
7277: DMPlexGetConeOrientation(dm, c, &ornt);
7278: /* A hex */
7279: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
7280: orntNew[0] = ornt[0];
7281: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */
7282: orntNew[1] = 0;
7283: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
7284: orntNew[2] = ornt[2];
7285: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */
7286: orntNew[3] = 0;
7287: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */
7288: orntNew[4] = 0;
7289: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
7290: orntNew[5] = ornt[5];
7291: DMPlexSetCone(rdm, newp+0, coneNew);
7292: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
7293: #if defined(PETSC_USE_DEBUG)
7294: 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);
7295: for (p = 0; p < 6; ++p) {
7296: 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);
7297: }
7298: #endif
7299: /* B hex */
7300: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
7301: orntNew[0] = ornt[0];
7302: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */
7303: orntNew[1] = 0;
7304: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */
7305: orntNew[2] = -1;
7306: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
7307: orntNew[3] = ornt[3];
7308: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */
7309: orntNew[4] = 0;
7310: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
7311: orntNew[5] = ornt[5];
7312: DMPlexSetCone(rdm, newp+1, coneNew);
7313: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
7314: #if defined(PETSC_USE_DEBUG)
7315: 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);
7316: for (p = 0; p < 6; ++p) {
7317: 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);
7318: }
7319: #endif
7320: /* C hex */
7321: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
7322: orntNew[0] = ornt[0];
7323: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */
7324: orntNew[1] = 0;
7325: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */
7326: orntNew[2] = -1;
7327: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
7328: orntNew[3] = ornt[3];
7329: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
7330: orntNew[4] = ornt[4];
7331: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */
7332: orntNew[5] = -4;
7333: DMPlexSetCone(rdm, newp+2, coneNew);
7334: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
7335: #if defined(PETSC_USE_DEBUG)
7336: 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);
7337: for (p = 0; p < 6; ++p) {
7338: 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);
7339: }
7340: #endif
7341: /* D hex */
7342: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
7343: orntNew[0] = ornt[0];
7344: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */
7345: orntNew[1] = 0;
7346: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
7347: orntNew[2] = ornt[2];
7348: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */
7349: orntNew[3] = 0;
7350: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
7351: orntNew[4] = ornt[4];
7352: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */
7353: orntNew[5] = -4;
7354: DMPlexSetCone(rdm, newp+3, coneNew);
7355: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
7356: #if defined(PETSC_USE_DEBUG)
7357: 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);
7358: for (p = 0; p < 6; ++p) {
7359: 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);
7360: }
7361: #endif
7362: /* E hex */
7363: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */
7364: orntNew[0] = -4;
7365: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
7366: orntNew[1] = ornt[1];
7367: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
7368: orntNew[2] = ornt[2];
7369: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */
7370: orntNew[3] = 0;
7371: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */
7372: orntNew[4] = -1;
7373: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
7374: orntNew[5] = ornt[5];
7375: DMPlexSetCone(rdm, newp+4, coneNew);
7376: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
7377: #if defined(PETSC_USE_DEBUG)
7378: 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);
7379: for (p = 0; p < 6; ++p) {
7380: 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);
7381: }
7382: #endif
7383: /* F hex */
7384: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */
7385: orntNew[0] = -4;
7386: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
7387: orntNew[1] = ornt[1];
7388: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
7389: orntNew[2] = ornt[2];
7390: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */
7391: orntNew[3] = -1;
7392: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
7393: orntNew[4] = ornt[4];
7394: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */
7395: orntNew[5] = 1;
7396: DMPlexSetCone(rdm, newp+5, coneNew);
7397: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
7398: #if defined(PETSC_USE_DEBUG)
7399: 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);
7400: for (p = 0; p < 6; ++p) {
7401: 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);
7402: }
7403: #endif
7404: /* G hex */
7405: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */
7406: orntNew[0] = -4;
7407: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
7408: orntNew[1] = ornt[1];
7409: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */
7410: orntNew[2] = 0;
7411: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
7412: orntNew[3] = ornt[3];
7413: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
7414: orntNew[4] = ornt[4];
7415: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */
7416: orntNew[5] = -3;
7417: DMPlexSetCone(rdm, newp+6, coneNew);
7418: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
7419: #if defined(PETSC_USE_DEBUG)
7420: 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);
7421: for (p = 0; p < 6; ++p) {
7422: 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);
7423: }
7424: #endif
7425: /* H hex */
7426: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */
7427: orntNew[0] = -4;
7428: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
7429: orntNew[1] = ornt[1];
7430: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */
7431: orntNew[2] = -1;
7432: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
7433: orntNew[3] = ornt[3];
7434: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */
7435: orntNew[4] = 3;
7436: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
7437: orntNew[5] = ornt[5];
7438: DMPlexSetCone(rdm, newp+7, coneNew);
7439: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
7440: #if defined(PETSC_USE_DEBUG)
7441: 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);
7442: for (p = 0; p < 6; ++p) {
7443: 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);
7444: }
7445: #endif
7446: }
7447: /* Hybrid cells have 6 faces: Front, Back, Sides */
7448: /*
7449: 3---------2---------2
7450: | | |
7451: | D 2 C |
7452: | | |
7453: 3----3----0----1----1
7454: | | |
7455: | A 0 B |
7456: | | |
7457: 0---------0---------1
7458: */
7459: for (c = cMax; c < cEnd; ++c) {
7460: const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4;
7461: const PetscInt *cone, *ornt, *fornt;
7462: PetscInt coneNew[6], orntNew[6], o, of, i;
7464: DMPlexGetCone(dm, c, &cone);
7465: DMPlexGetConeOrientation(dm, c, &ornt);
7466: DMPlexGetConeOrientation(dm, cone[0], &fornt);
7467: o = ornt[0] < 0 ? -1 : 1;
7468: for (r = 0; r < 4; ++r) {
7469: PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
7470: PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
7471: PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
7472: 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]);
7473: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA;
7474: orntNew[0] = ornt[0];
7475: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA;
7476: orntNew[1] = ornt[0];
7477: of = fornt[edgeA] < 0 ? -1 : 1;
7478: i = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
7479: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
7480: orntNew[i] = ornt[edgeA];
7481: i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
7482: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA;
7483: orntNew[i] = 0;
7484: i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
7485: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB;
7486: orntNew[i] = -2;
7487: of = fornt[edgeB] < 0 ? -1 : 1;
7488: i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
7489: coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
7490: orntNew[i] = ornt[edgeB];
7491: DMPlexSetCone(rdm, newp+r, coneNew);
7492: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
7493: #if defined(PETSC_USE_DEBUG)
7494: 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);
7495: for (p = 0; p < 2; ++p) {
7496: 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);
7497: }
7498: for (p = 2; p < 6; ++p) {
7499: 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);
7500: }
7501: #endif
7502: }
7503: }
7504: /* Interior split faces have 4 edges and the same cells as the parent */
7505: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
7506: PetscMalloc1(4 + maxSupportSize*2, &supportRef);
7507: for (f = fStart; f < fMax; ++f) {
7508: for (r = 0; r < 4; ++r) {
7509: /* TODO: This can come from GetFaces_Internal() */
7510: 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};
7511: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
7512: const PetscInt *cone, *ornt, *support;
7513: PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s;
7515: DMPlexGetCone(dm, f, &cone);
7516: DMPlexGetConeOrientation(dm, f, &ornt);
7517: coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
7518: orntNew[(r+3)%4] = ornt[(r+3)%4];
7519: coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
7520: orntNew[(r+0)%4] = ornt[r];
7521: coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
7522: orntNew[(r+1)%4] = 0;
7523: coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
7524: orntNew[(r+2)%4] = -2;
7525: DMPlexSetCone(rdm, newp, coneNew);
7526: DMPlexSetConeOrientation(rdm, newp, orntNew);
7527: #if defined(PETSC_USE_DEBUG)
7528: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7529: for (p = 0; p < 4; ++p) {
7530: 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);
7531: }
7532: #endif
7533: DMPlexGetSupportSize(dm, f, &supportSize);
7534: DMPlexGetSupport(dm, f, &support);
7535: for (s = 0; s < supportSize; ++s) {
7536: PetscInt subf;
7537: DMPlexGetConeSize(dm, support[s], &coneSize);
7538: DMPlexGetCone(dm, support[s], &cone);
7539: DMPlexGetConeOrientation(dm, support[s], &ornt);
7540: for (c = 0; c < coneSize; ++c) {
7541: if (cone[c] == f) break;
7542: }
7543: subf = GetQuadSubfaceInverse_Static(ornt[c], r);
7544: if (support[s] < cMax) {
7545: supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
7546: } else {
7547: supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf;
7548: }
7549: }
7550: DMPlexSetSupport(rdm, newp, supportRef);
7551: #if defined(PETSC_USE_DEBUG)
7552: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7553: for (p = 0; p < supportSize; ++p) {
7554: 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);
7555: }
7556: #endif
7557: }
7558: }
7559: /* Interior cell faces have 4 edges and 2 cells */
7560: for (c = cStart; c < cMax; ++c) {
7561: 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};
7562: const PetscInt *cone, *ornt;
7563: PetscInt newp, coneNew[4], orntNew[4], supportNew[2];
7565: DMPlexGetCone(dm, c, &cone);
7566: DMPlexGetConeOrientation(dm, c, &ornt);
7567: /* A-D face */
7568: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
7569: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
7570: orntNew[0] = 0;
7571: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7572: orntNew[1] = 0;
7573: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7574: orntNew[2] = -2;
7575: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
7576: orntNew[3] = -2;
7577: DMPlexSetCone(rdm, newp, coneNew);
7578: DMPlexSetConeOrientation(rdm, newp, orntNew);
7579: #if defined(PETSC_USE_DEBUG)
7580: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7581: for (p = 0; p < 4; ++p) {
7582: 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);
7583: }
7584: #endif
7585: /* C-D face */
7586: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
7587: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
7588: orntNew[0] = 0;
7589: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7590: orntNew[1] = 0;
7591: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7592: orntNew[2] = -2;
7593: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
7594: orntNew[3] = -2;
7595: DMPlexSetCone(rdm, newp, coneNew);
7596: DMPlexSetConeOrientation(rdm, newp, orntNew);
7597: #if defined(PETSC_USE_DEBUG)
7598: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7599: for (p = 0; p < 4; ++p) {
7600: 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);
7601: }
7602: #endif
7603: /* B-C face */
7604: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
7605: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
7606: orntNew[0] = -2;
7607: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
7608: orntNew[1] = 0;
7609: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7610: orntNew[2] = 0;
7611: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7612: orntNew[3] = -2;
7613: DMPlexSetCone(rdm, newp, coneNew);
7614: DMPlexSetConeOrientation(rdm, newp, orntNew);
7615: #if defined(PETSC_USE_DEBUG)
7616: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7617: for (p = 0; p < 4; ++p) {
7618: 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);
7619: }
7620: #endif
7621: /* A-B face */
7622: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
7623: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
7624: orntNew[0] = -2;
7625: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
7626: orntNew[1] = 0;
7627: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7628: orntNew[2] = 0;
7629: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
7630: orntNew[3] = -2;
7631: DMPlexSetCone(rdm, newp, coneNew);
7632: DMPlexSetConeOrientation(rdm, newp, orntNew);
7633: #if defined(PETSC_USE_DEBUG)
7634: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7635: for (p = 0; p < 4; ++p) {
7636: 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);
7637: }
7638: #endif
7639: /* E-F face */
7640: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
7641: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7642: orntNew[0] = -2;
7643: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
7644: orntNew[1] = -2;
7645: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
7646: orntNew[2] = 0;
7647: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7648: orntNew[3] = 0;
7649: DMPlexSetCone(rdm, newp, coneNew);
7650: DMPlexSetConeOrientation(rdm, newp, orntNew);
7651: #if defined(PETSC_USE_DEBUG)
7652: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7653: for (p = 0; p < 4; ++p) {
7654: 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);
7655: }
7656: #endif
7657: /* F-G face */
7658: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
7659: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7660: orntNew[0] = -2;
7661: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
7662: orntNew[1] = -2;
7663: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
7664: orntNew[2] = 0;
7665: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7666: orntNew[3] = 0;
7667: DMPlexSetCone(rdm, newp, coneNew);
7668: DMPlexSetConeOrientation(rdm, newp, orntNew);
7669: #if defined(PETSC_USE_DEBUG)
7670: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7671: for (p = 0; p < 4; ++p) {
7672: 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);
7673: }
7674: #endif
7675: /* G-H face */
7676: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
7677: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
7678: orntNew[0] = -2;
7679: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
7680: orntNew[1] = 0;
7681: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7682: orntNew[2] = 0;
7683: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7684: orntNew[3] = -2;
7685: DMPlexSetCone(rdm, newp, coneNew);
7686: DMPlexSetConeOrientation(rdm, newp, orntNew);
7687: #if defined(PETSC_USE_DEBUG)
7688: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7689: for (p = 0; p < 4; ++p) {
7690: 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);
7691: }
7692: #endif
7693: /* E-H face */
7694: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
7695: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7696: orntNew[0] = -2;
7697: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
7698: orntNew[1] = -2;
7699: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
7700: orntNew[2] = 0;
7701: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
7702: orntNew[3] = 0;
7703: DMPlexSetCone(rdm, newp, coneNew);
7704: DMPlexSetConeOrientation(rdm, newp, orntNew);
7705: #if defined(PETSC_USE_DEBUG)
7706: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7707: for (p = 0; p < 4; ++p) {
7708: 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);
7709: }
7710: #endif
7711: /* A-E face */
7712: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
7713: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
7714: orntNew[0] = 0;
7715: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7716: orntNew[1] = 0;
7717: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7718: orntNew[2] = -2;
7719: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
7720: orntNew[3] = -2;
7721: DMPlexSetCone(rdm, newp, coneNew);
7722: DMPlexSetConeOrientation(rdm, newp, orntNew);
7723: #if defined(PETSC_USE_DEBUG)
7724: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7725: for (p = 0; p < 4; ++p) {
7726: 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);
7727: }
7728: #endif
7729: /* D-F face */
7730: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
7731: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
7732: orntNew[0] = -2;
7733: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
7734: orntNew[1] = 0;
7735: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7736: orntNew[2] = 0;
7737: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
7738: orntNew[3] = -2;
7739: DMPlexSetCone(rdm, newp, coneNew);
7740: DMPlexSetConeOrientation(rdm, newp, orntNew);
7741: #if defined(PETSC_USE_DEBUG)
7742: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7743: for (p = 0; p < 4; ++p) {
7744: 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);
7745: }
7746: #endif
7747: /* C-G face */
7748: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
7749: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
7750: orntNew[0] = -2;
7751: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
7752: orntNew[1] = -2;
7753: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
7754: orntNew[2] = 0;
7755: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7756: orntNew[3] = 0;
7757: DMPlexSetCone(rdm, newp, coneNew);
7758: DMPlexSetConeOrientation(rdm, newp, orntNew);
7759: #if defined(PETSC_USE_DEBUG)
7760: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7761: for (p = 0; p < 4; ++p) {
7762: 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);
7763: }
7764: #endif
7765: /* B-H face */
7766: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
7767: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
7768: orntNew[0] = 0;
7769: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
7770: orntNew[1] = -2;
7771: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
7772: orntNew[2] = -2;
7773: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
7774: orntNew[3] = 0;
7775: DMPlexSetCone(rdm, newp, coneNew);
7776: DMPlexSetConeOrientation(rdm, newp, orntNew);
7777: #if defined(PETSC_USE_DEBUG)
7778: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7779: for (p = 0; p < 4; ++p) {
7780: 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);
7781: }
7782: #endif
7783: for (r = 0; r < 12; ++r) {
7784: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
7785: supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
7786: supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
7787: DMPlexSetSupport(rdm, newp, supportNew);
7788: #if defined(PETSC_USE_DEBUG)
7789: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew);
7790: for (p = 0; p < 2; ++p) {
7791: 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);
7792: }
7793: #endif
7794: }
7795: }
7796: /* Hybrid split faces have 4 edges and same cells */
7797: for (f = fMax; f < fEnd; ++f) {
7798: const PetscInt *cone, *ornt, *support;
7799: PetscInt coneNew[4], orntNew[4];
7800: PetscInt supportNew[2], size, s, c;
7802: DMPlexGetCone(dm, f, &cone);
7803: DMPlexGetConeOrientation(dm, f, &ornt);
7804: DMPlexGetSupportSize(dm, f, &size);
7805: DMPlexGetSupport(dm, f, &support);
7806: for (r = 0; r < 2; ++r) {
7807: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
7809: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
7810: orntNew[0] = ornt[0];
7811: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
7812: orntNew[1] = ornt[1];
7813: coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
7814: orntNew[2+r] = 0;
7815: coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
7816: orntNew[3-r] = 0;
7817: DMPlexSetCone(rdm, newp, coneNew);
7818: DMPlexSetConeOrientation(rdm, newp, orntNew);
7819: #if defined(PETSC_USE_DEBUG)
7820: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
7821: for (p = 0; p < 2; ++p) {
7822: 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);
7823: }
7824: for (p = 2; p < 4; ++p) {
7825: 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);
7826: }
7827: #endif
7828: for (s = 0; s < size; ++s) {
7829: const PetscInt *coneCell, *orntCell, *fornt;
7830: PetscInt o, of;
7832: DMPlexGetCone(dm, support[s], &coneCell);
7833: DMPlexGetConeOrientation(dm, support[s], &orntCell);
7834: o = orntCell[0] < 0 ? -1 : 1;
7835: for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
7836: if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]);
7837: DMPlexGetConeOrientation(dm, coneCell[0], &fornt);
7838: of = fornt[c-2] < 0 ? -1 : 1;
7839: supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4;
7840: }
7841: DMPlexSetSupport(rdm, newp, supportNew);
7842: #if defined(PETSC_USE_DEBUG)
7843: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew);
7844: for (p = 0; p < size; ++p) {
7845: 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);
7846: }
7847: #endif
7848: }
7849: }
7850: /* Hybrid cell faces have 4 edges and 2 cells */
7851: for (c = cMax; c < cEnd; ++c) {
7852: PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
7853: const PetscInt *cone, *ornt;
7854: PetscInt coneNew[4], orntNew[4];
7855: PetscInt supportNew[2];
7857: DMPlexGetCone(dm, c, &cone);
7858: DMPlexGetConeOrientation(dm, c, &ornt);
7859: for (r = 0; r < 4; ++r) {
7860: #if 0
7861: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
7862: orntNew[0] = 0;
7863: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
7864: orntNew[1] = 0;
7865: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
7866: orntNew[2] = 0;
7867: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
7868: orntNew[3] = 0;
7869: #else
7870: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
7871: orntNew[0] = 0;
7872: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
7873: orntNew[1] = 0;
7874: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
7875: orntNew[2] = 0;
7876: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
7877: orntNew[3] = 0;
7878: #endif
7879: DMPlexSetCone(rdm, newp+r, coneNew);
7880: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
7881: #if defined(PETSC_USE_DEBUG)
7882: 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);
7883: for (p = 0; p < 2; ++p) {
7884: 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);
7885: }
7886: for (p = 2; p < 4; ++p) {
7887: 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);
7888: }
7889: #endif
7890: supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
7891: supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
7892: DMPlexSetSupport(rdm, newp+r, supportNew);
7893: #if defined(PETSC_USE_DEBUG)
7894: 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);
7895: for (p = 0; p < 2; ++p) {
7896: 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);
7897: }
7898: #endif
7899: }
7900: }
7901: /* Interior split edges have 2 vertices and the same faces as the parent */
7902: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
7903: for (e = eStart; e < eMax; ++e) {
7904: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
7906: for (r = 0; r < 2; ++r) {
7907: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
7908: const PetscInt *cone, *ornt, *support;
7909: PetscInt coneNew[2], coneSize, c, supportSize, s;
7911: DMPlexGetCone(dm, e, &cone);
7912: coneNew[0] = vStartNew + (cone[0] - vStart);
7913: coneNew[1] = vStartNew + (cone[1] - vStart);
7914: coneNew[(r+1)%2] = newv;
7915: DMPlexSetCone(rdm, newp, coneNew);
7916: #if defined(PETSC_USE_DEBUG)
7917: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7918: for (p = 0; p < 2; ++p) {
7919: 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);
7920: }
7921: #endif
7922: DMPlexGetSupportSize(dm, e, &supportSize);
7923: DMPlexGetSupport(dm, e, &support);
7924: for (s = 0; s < supportSize; ++s) {
7925: DMPlexGetConeSize(dm, support[s], &coneSize);
7926: DMPlexGetCone(dm, support[s], &cone);
7927: DMPlexGetConeOrientation(dm, support[s], &ornt);
7928: for (c = 0; c < coneSize; ++c) {
7929: if (cone[c] == e) break;
7930: }
7931: if (support[s] < fMax) {
7932: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
7933: } else {
7934: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
7935: }
7936: }
7937: DMPlexSetSupport(rdm, newp, supportRef);
7938: #if defined(PETSC_USE_DEBUG)
7939: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7940: for (p = 0; p < supportSize; ++p) {
7941: 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);
7942: }
7943: #endif
7944: }
7945: }
7946: /* Interior face edges have 2 vertices and 2+cells faces */
7947: for (f = fStart; f < fMax; ++f) {
7948: 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};
7949: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
7950: const PetscInt *cone, *coneCell, *orntCell, *support;
7951: PetscInt coneNew[2], coneSize, c, supportSize, s;
7953: DMPlexGetCone(dm, f, &cone);
7954: for (r = 0; r < 4; ++r) {
7955: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
7957: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
7958: coneNew[1] = newv;
7959: DMPlexSetCone(rdm, newp, coneNew);
7960: #if defined(PETSC_USE_DEBUG)
7961: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7962: for (p = 0; p < 2; ++p) {
7963: 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);
7964: }
7965: #endif
7966: DMPlexGetSupportSize(dm, f, &supportSize);
7967: DMPlexGetSupport(dm, f, &support);
7968: supportRef[0] = fStartNew + (f - fStart)*4 + r;
7969: supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
7970: for (s = 0; s < supportSize; ++s) {
7971: DMPlexGetConeSize(dm, support[s], &coneSize);
7972: DMPlexGetCone(dm, support[s], &coneCell);
7973: DMPlexGetConeOrientation(dm, support[s], &orntCell);
7974: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
7975: if (support[s] < cMax) {
7976: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
7977: } else {
7978: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
7979: }
7980: }
7981: DMPlexSetSupport(rdm, newp, supportRef);
7982: #if defined(PETSC_USE_DEBUG)
7983: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
7984: for (p = 0; p < 2+supportSize; ++p) {
7985: 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);
7986: }
7987: #endif
7988: }
7989: }
7990: /* Interior cell edges have 2 vertices and 4 faces */
7991: for (c = cStart; c < cMax; ++c) {
7992: 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};
7993: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
7994: const PetscInt *cone;
7995: PetscInt coneNew[2], supportNew[4];
7997: DMPlexGetCone(dm, c, &cone);
7998: for (r = 0; r < 6; ++r) {
7999: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
8001: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
8002: coneNew[1] = newv;
8003: DMPlexSetCone(rdm, newp, coneNew);
8004: #if defined(PETSC_USE_DEBUG)
8005: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
8006: for (p = 0; p < 2; ++p) {
8007: 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);
8008: }
8009: #endif
8010: for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
8011: DMPlexSetSupport(rdm, newp, supportNew);
8012: #if defined(PETSC_USE_DEBUG)
8013: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew);
8014: for (p = 0; p < 4; ++p) {
8015: 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);
8016: }
8017: #endif
8018: }
8019: }
8020: /* Hybrid edges have two vertices and the same faces */
8021: for (e = eMax; e < eEnd; ++e) {
8022: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
8023: const PetscInt *cone, *support, *fcone;
8024: PetscInt coneNew[2], size, fsize, s;
8026: DMPlexGetCone(dm, e, &cone);
8027: DMPlexGetSupportSize(dm, e, &size);
8028: DMPlexGetSupport(dm, e, &support);
8029: coneNew[0] = vStartNew + (cone[0] - vStart);
8030: coneNew[1] = vStartNew + (cone[1] - vStart);
8031: DMPlexSetCone(rdm, newp, coneNew);
8032: #if defined(PETSC_USE_DEBUG)
8033: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8034: for (p = 0; p < 2; ++p) {
8035: 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);
8036: }
8037: #endif
8038: for (s = 0; s < size; ++s) {
8039: DMPlexGetConeSize(dm, support[s], &fsize);
8040: DMPlexGetCone(dm, support[s], &fcone);
8041: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
8042: if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]);
8043: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
8044: }
8045: DMPlexSetSupport(rdm, newp, supportRef);
8046: #if defined(PETSC_USE_DEBUG)
8047: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8048: for (p = 0; p < size; ++p) {
8049: 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);
8050: }
8051: #endif
8052: }
8053: /* Hybrid face edges have 2 vertices and 2+cells faces */
8054: for (f = fMax; f < fEnd; ++f) {
8055: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
8056: const PetscInt *cone, *support, *ccone, *cornt;
8057: PetscInt coneNew[2], size, csize, s;
8059: DMPlexGetCone(dm, f, &cone);
8060: DMPlexGetSupportSize(dm, f, &size);
8061: DMPlexGetSupport(dm, f, &support);
8062: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
8063: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
8064: DMPlexSetCone(rdm, newp, coneNew);
8065: #if defined(PETSC_USE_DEBUG)
8066: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8067: for (p = 0; p < 2; ++p) {
8068: 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);
8069: }
8070: #endif
8071: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
8072: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
8073: for (s = 0; s < size; ++s) {
8074: DMPlexGetConeSize(dm, support[s], &csize);
8075: DMPlexGetCone(dm, support[s], &ccone);
8076: DMPlexGetConeOrientation(dm, support[s], &cornt);
8077: for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
8078: 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]);
8079: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
8080: }
8081: DMPlexSetSupport(rdm, newp, supportRef);
8082: #if defined(PETSC_USE_DEBUG)
8083: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8084: for (p = 0; p < 2+size; ++p) {
8085: 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);
8086: }
8087: #endif
8088: }
8089: /* Hybrid cell edges have 2 vertices and 4 faces */
8090: for (c = cMax; c < cEnd; ++c) {
8091: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
8092: const PetscInt *cone, *support;
8093: PetscInt coneNew[2], size;
8095: DMPlexGetCone(dm, c, &cone);
8096: DMPlexGetSupportSize(dm, c, &size);
8097: DMPlexGetSupport(dm, c, &support);
8098: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
8099: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
8100: DMPlexSetCone(rdm, newp, coneNew);
8101: #if defined(PETSC_USE_DEBUG)
8102: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8103: for (p = 0; p < 2; ++p) {
8104: 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);
8105: }
8106: #endif
8107: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
8108: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
8109: supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
8110: supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
8111: DMPlexSetSupport(rdm, newp, supportRef);
8112: #if defined(PETSC_USE_DEBUG)
8113: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew);
8114: for (p = 0; p < 4; ++p) {
8115: 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);
8116: }
8117: #endif
8118: }
8119: /* Interior vertices have identical supports */
8120: for (v = vStart; v < vEnd; ++v) {
8121: const PetscInt newp = vStartNew + (v - vStart);
8122: const PetscInt *support, *cone;
8123: PetscInt size, s;
8125: DMPlexGetSupportSize(dm, v, &size);
8126: DMPlexGetSupport(dm, v, &support);
8127: for (s = 0; s < size; ++s) {
8128: PetscInt r = 0;
8130: DMPlexGetCone(dm, support[s], &cone);
8131: if (cone[1] == v) r = 1;
8132: if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
8133: else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
8134: }
8135: DMPlexSetSupport(rdm, newp, supportRef);
8136: #if defined(PETSC_USE_DEBUG)
8137: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
8138: for (p = 0; p < size; ++p) {
8139: 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);
8140: }
8141: #endif
8142: }
8143: /* Interior edge vertices have 2 + faces supports */
8144: for (e = eStart; e < eMax; ++e) {
8145: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
8146: const PetscInt *cone, *support;
8147: PetscInt size, s;
8149: DMPlexGetSupportSize(dm, e, &size);
8150: DMPlexGetSupport(dm, e, &support);
8151: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
8152: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
8153: for (s = 0; s < size; ++s) {
8154: PetscInt r;
8156: DMPlexGetCone(dm, support[s], &cone);
8157: for (r = 0; r < 4; ++r) if (cone[r] == e) break;
8158: if (support[s] < fMax) {
8159: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
8160: } else {
8161: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
8162: }
8163: }
8164: DMPlexSetSupport(rdm, newp, supportRef);
8165: #if defined(PETSC_USE_DEBUG)
8166: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
8167: for (p = 0; p < 2+size; ++p) {
8168: 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);
8169: }
8170: #endif
8171: }
8172: /* Interior face vertices have 4 + cells supports */
8173: for (f = fStart; f < fMax; ++f) {
8174: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
8175: const PetscInt *cone, *support;
8176: PetscInt size, s;
8178: DMPlexGetSupportSize(dm, f, &size);
8179: DMPlexGetSupport(dm, f, &support);
8180: for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
8181: for (s = 0; s < size; ++s) {
8182: PetscInt r;
8184: DMPlexGetCone(dm, support[s], &cone);
8185: for (r = 0; r < 6; ++r) if (cone[r] == f) break;
8186: if (support[s] < cMax) {
8187: supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
8188: } else {
8189: supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
8190: }
8191: }
8192: DMPlexSetSupport(rdm, newp, supportRef);
8193: #if defined(PETSC_USE_DEBUG)
8194: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew);
8195: for (p = 0; p < 4+size; ++p) {
8196: 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);
8197: }
8198: #endif
8199: }
8200: /* Cell vertices have 6 supports */
8201: for (c = cStart; c < cMax; ++c) {
8202: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
8203: PetscInt supportNew[6];
8205: for (r = 0; r < 6; ++r) {
8206: supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
8207: }
8208: DMPlexSetSupport(rdm, newp, supportNew);
8209: }
8210: PetscFree(supportRef);
8211: break;
8212: default:
8213: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
8214: }
8215: return(0);
8216: }
8218: static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
8219: {
8220: PetscSection coordSection, coordSectionNew;
8221: Vec coordinates, coordinatesNew;
8222: PetscScalar *coords, *coordsNew;
8223: const PetscInt numVertices = depthSize ? depthSize[0] : 0;
8224: PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax;
8225: PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
8226: PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL;
8227: VecType vtype;
8228: PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE;
8229: const PetscReal *maxCell, *L;
8230: const DMBoundaryType *bd;
8231: PetscErrorCode ierr;
8234: DMGetDimension(dm, &dim);
8235: DMPlexGetDepth(dm, &depth);
8236: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
8237: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
8238: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
8239: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
8240: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);
8241: if (cMax < 0) cMax = cEnd;
8242: if (fMax < 0) fMax = fEnd;
8243: if (eMax < 0) eMax = eEnd;
8244: GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);
8245: GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);
8246: DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);
8247: /* Determine if we need to localize coordinates when generating them */
8248: if (isperiodic && !maxCell) {
8249: DMGetCoordinatesLocalized(dm, &localize);
8250: if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized");
8251: }
8252: if (isperiodic) {
8253: PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");
8254: PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);
8255: PetscOptionsEnd();
8256: if (localize) {
8257: DMLocalizeCoordinates(dm);
8258: }
8259: }
8260: DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);
8262: DMGetCoordinateSection(dm, &coordSection);
8263: PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);
8264: PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);
8265: PetscSectionSetNumFields(coordSectionNew, 1);
8266: PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);
8268: if (localize) {
8269: PetscInt p, r, newp, *pi;
8271: /* New coordinates will be already localized on the cell */
8272: PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);
8274: /* We need the parentId to properly localize coordinates */
8275: PetscMalloc1(cEndNew-cStartNew,&pi);
8276: switch (refiner) {
8277: case REFINER_NOOP:
8278: break;
8279: case REFINER_SIMPLEX_1D:
8280: for (p = cStart; p < cEnd; ++p) {
8281: for (r = 0; r < 2; ++r) {
8282: newp = (p - cStart)*2 + r;
8283: pi[newp] = p;
8284: }
8285: }
8286: break;
8287: case REFINER_SIMPLEX_2D:
8288: for (p = cStart; p < cEnd; ++p) {
8289: for (r = 0; r < 4; ++r) {
8290: newp = (p - cStart)*4 + r;
8291: pi[newp] = p;
8292: }
8293: }
8294: break;
8295: case REFINER_HEX_2D:
8296: for (p = cStart; p < cEnd; ++p) {
8297: for (r = 0; r < 4; ++r) {
8298: newp = (p - cStart)*4 + r;
8299: pi[newp] = p;
8300: }
8301: }
8302: break;
8303: case REFINER_SIMPLEX_TO_HEX_2D:
8304: for (p = cStart; p < cEnd; ++p) {
8305: for (r = 0; r < 3; ++r) {
8306: newp = (p - cStart)*3 + r;
8307: pi[newp] = p;
8308: }
8309: }
8310: break;
8311: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
8312: for (p = cStart; p < cMax; ++p) {
8313: for (r = 0; r < 3; ++r) {
8314: newp = (p - cStart)*3 + r;
8315: pi[newp] = p;
8316: }
8317: }
8318: for (p = cMax; p < cEnd; ++p) {
8319: for (r = 0; r < 4; ++r) {
8320: newp = (cMax - cStart)*3 + (p - cMax)*4 + r;
8321: pi[newp] = p;
8322: }
8323: }
8324: /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */
8325: cMax = cEnd;
8326: eMax = eEnd;
8327: break;
8328: case REFINER_HYBRID_SIMPLEX_2D:
8329: for (p = cStart; p < cMax; ++p) {
8330: for (r = 0; r < 4; ++r) {
8331: newp = (p - cStart)*4 + r;
8332: pi[newp] = p;
8333: }
8334: }
8335: for (p = cMax; p < cEnd; ++p) {
8336: for (r = 0; r < 2; ++r) {
8337: newp = (cMax - cStart)*4 + (p - cMax)*2 + r;
8338: pi[newp] = p;
8339: }
8340: }
8341: break;
8342: case REFINER_HYBRID_HEX_2D:
8343: for (p = cStart; p < cMax; ++p) {
8344: for (r = 0; r < 4; ++r) {
8345: newp = (p - cStart)*4 + r;
8346: pi[newp] = p;
8347: }
8348: }
8349: for (p = cMax; p < cEnd; ++p) {
8350: for (r = 0; r < 2; ++r) {
8351: newp = (cMax - cStart)*4 + (p - cMax)*2 + r;
8352: pi[newp] = p;
8353: }
8354: }
8355: break;
8356: case REFINER_SIMPLEX_3D:
8357: for (p = cStart; p < cEnd; ++p) {
8358: for (r = 0; r < 8; ++r) {
8359: newp = (p - cStart)*8 + r;
8360: pi[newp] = p;
8361: }
8362: }
8363: break;
8364: case REFINER_HYBRID_SIMPLEX_3D:
8365: for (p = cStart; p < cMax; ++p) {
8366: for (r = 0; r < 8; ++r) {
8367: newp = (p - cStart)*8 + r;
8368: pi[newp] = p;
8369: }
8370: }
8371: for (p = cMax; p < cEnd; ++p) {
8372: for (r = 0; r < 4; ++r) {
8373: newp = (cMax - cStart)*8 + (p - cMax)*4 + r;
8374: pi[newp] = p;
8375: }
8376: }
8377: break;
8378: case REFINER_SIMPLEX_TO_HEX_3D:
8379: for (p = cStart; p < cEnd; ++p) {
8380: for (r = 0; r < 4; ++r) {
8381: newp = (p - cStart)*4 + r;
8382: pi[newp] = p;
8383: }
8384: }
8385: break;
8386: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
8387: for (p = cStart; p < cMax; ++p) {
8388: for (r = 0; r < 4; ++r) {
8389: newp = (p - cStart)*4 + r;
8390: pi[newp] = p;
8391: }
8392: }
8393: for (p = cMax; p < cEnd; ++p) {
8394: for (r = 0; r < 3; ++r) {
8395: newp = (cMax - cStart)*4 + (p - cMax)*3 + r;
8396: pi[newp] = p;
8397: }
8398: }
8399: break;
8400: case REFINER_HEX_3D:
8401: for (p = cStart; p < cEnd; ++p) {
8402: for (r = 0; r < 8; ++r) {
8403: newp = (p - cStart)*8 + r;
8404: pi[newp] = p;
8405: }
8406: }
8407: break;
8408: case REFINER_HYBRID_HEX_3D:
8409: for (p = cStart; p < cMax; ++p) {
8410: for (r = 0; r < 8; ++r) {
8411: newp = (p - cStart)*8 + r;
8412: pi[newp] = p;
8413: }
8414: }
8415: for (p = cMax; p < cEnd; ++p) {
8416: for (r = 0; r < 4; ++r) {
8417: newp = (cMax - cStart)*8 + (p - cMax)*4 + r;
8418: pi[newp] = p;
8419: }
8420: }
8421: break;
8422: default:
8423: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
8424: }
8425: parentId = pi;
8426: } else {
8427: /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */
8428: if (REFINER_HYBRID_SIMPLEX_TO_HEX_2D == refiner) { cMax = cEnd; eMax = eEnd; }
8429: PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);
8430: }
8432: /* All vertices have the spaceDim coordinates */
8433: if (localize) {
8434: PetscInt c;
8436: for (c = cStartNew; c < cEndNew; ++c) {
8437: PetscInt *cone = NULL;
8438: PetscInt closureSize, coneSize = 0, p, pdof;
8440: PetscSectionGetDof(coordSection, parentId[c], &pdof);
8441: if (pdof) { /* localize on all cells that are refinement of a localized parent cell */
8442: DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8443: for (p = 0; p < closureSize*2; p += 2) {
8444: const PetscInt point = cone[p];
8445: if ((point >= vStartNew) && (point < vEndNew)) coneSize++;
8446: }
8447: DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8448: PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);
8449: PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);
8450: }
8451: }
8452: }
8453: for (v = vStartNew; v < vStartNew+numVertices; ++v) {
8454: PetscSectionSetDof(coordSectionNew, v, spaceDim);
8455: PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);
8456: }
8457: PetscSectionSetUp(coordSectionNew);
8458: DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);
8459: DMGetCoordinatesLocal(dm, &coordinates);
8460: PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);
8461: VecCreate(PETSC_COMM_SELF, &coordinatesNew);
8462: PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");
8463: VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);
8464: VecGetBlockSize(coordinates, &bs);
8465: VecSetBlockSize(coordinatesNew, bs);
8466: VecGetType(coordinates, &vtype);
8467: VecSetType(coordinatesNew, vtype);
8468: VecGetArray(coordinates, &coords);
8469: VecGetArray(coordinatesNew, &coordsNew);
8471: switch (refiner) {
8472: case REFINER_NOOP: break;
8473: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
8474: case REFINER_SIMPLEX_TO_HEX_3D:
8475: case REFINER_HEX_3D:
8476: case REFINER_HYBRID_HEX_3D:
8477: /* Face vertices have the average of corner coordinates */
8478: for (f = fStart; f < fMax; ++f) {
8479: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
8480: PetscInt *cone = NULL;
8481: PetscInt closureSize, coneSize = 0, off[8], offnew, p, d;
8483: DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);
8484: for (p = 0; p < closureSize*2; p += 2) {
8485: const PetscInt point = cone[p];
8486: if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
8487: }
8488: if (localize) {
8489: const PetscInt *support = NULL;
8490: PetscInt *rStar = NULL;
8491: PetscInt supportSize, rStarSize, coff, s, ccoff[8];
8492: PetscBool cellfound = PETSC_FALSE;
8494: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8495: DMPlexGetSupportSize(dm,f,&supportSize);
8496: DMPlexGetSupport(dm,f,&support);
8497: /* Compute average of coordinates for each cell sharing the face */
8498: for (s = 0; s < supportSize; ++s) {
8499: PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 };
8500: PetscInt *cellCone = NULL;
8501: PetscInt cellClosureSize, cellConeSize = 0, cdof;
8502: const PetscInt cell = support[s];
8503: PetscBool copyoff = PETSC_FALSE;
8505: DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8506: for (p = 0; p < cellClosureSize*2; p += 2) {
8507: const PetscInt point = cellCone[p];
8508: if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point;
8509: }
8510: PetscSectionGetDof(coordSection, cell, &cdof);
8511: if (!cdof) { /* the parent cell does not have localized coordinates */
8512: cellfound = PETSC_TRUE;
8513: for (v = 0; v < coneSize; ++v) {
8514: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
8515: for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d];
8516: }
8517: for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
8518: } else {
8519: PetscSectionGetOffset(coordSection, cell, &coff);
8520: for (p = 0; p < coneSize; ++p) {
8521: const PetscInt tv = cone[p];
8522: PetscInt cv, voff;
8523: PetscBool locv = PETSC_TRUE;
8525: for (cv = 0; cv < cellConeSize; ++cv) {
8526: if (cellCone[cv] == tv) {
8527: ccoff[p] = spaceDim*cv + coff;
8528: break;
8529: }
8530: }
8531: if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D",tv);
8533: PetscSectionGetOffset(coordSection, cone[p], &voff);
8534: for (d = 0; d < spaceDim; ++d) {
8535: coordsNewAux[d] += coords[ccoff[p]+d];
8536: if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE;
8537: }
8538: if (locv && !cellfound) {
8539: cellfound = PETSC_TRUE;
8540: copyoff = PETSC_TRUE;
8541: }
8542: }
8543: for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
8545: /* Found a valid face for the "vertex" part of the Section (physical space)
8546: i.e., a face that has at least one corner in the physical space */
8547: if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p];
8548: }
8550: /* Localize new coordinates on each refined cell */
8551: for (v = 0; v < rStarSize*2; v += 2) {
8552: if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) {
8553: PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff;
8554: const PetscInt rcell = rStar[v];
8556: PetscSectionGetDof(coordSectionNew, rcell, &rcdof);
8557: if (!rcdof) continue;
8558: PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);
8559: DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8560: for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
8561: if (rcone[p] == newv) {
8562: for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d];
8563: break;
8564: }
8565: if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
8566: }
8567: DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8568: if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8569: }
8570: }
8571: DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8572: }
8573: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8574: if (!cellfound) {
8575: /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */
8576: needcoords = PETSC_TRUE;
8577: coneSize = 0;
8578: }
8579: } else {
8580: for (v = 0; v < coneSize; ++v) {
8581: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
8582: }
8583: }
8584: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8585: if (coneSize) {
8586: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
8587: for (v = 0; v < coneSize; ++v) {DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);}
8588: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
8589: } else {
8590: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
8591: }
8592: DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);
8593: }
8594: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
8595: case REFINER_SIMPLEX_TO_HEX_2D:
8596: case REFINER_HEX_2D:
8597: case REFINER_HYBRID_HEX_2D:
8598: case REFINER_SIMPLEX_1D:
8599: /* Cell vertices have the average of corner coordinates */
8600: for (c = cStart; c < cMax; ++c) {
8601: const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
8602: PetscInt *cone = NULL;
8603: PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0;
8605: DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);
8606: for (p = 0; p < closureSize*2; p += 2) {
8607: const PetscInt point = cone[p];
8608: if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
8609: }
8610: if (localize) {
8611: PetscSectionGetDof(coordSection, c, &cdof);
8612: }
8613: if (cdof) {
8614: PetscInt coff;
8616: PetscSectionGetOffset(coordSection, c, &coff);
8617: for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff;
8618: } else {
8619: for (v = 0; v < coneSize; ++v) {
8620: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
8621: }
8622: }
8623: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8624: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
8625: for (v = 0; v < coneSize; ++v) {DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);}
8626: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
8627: DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);
8629: /* Localize new coordinates on each refined cell */
8630: if (cdof) {
8631: PetscInt *rStar = NULL, rStarSize;
8633: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8634: for (v = 0; v < rStarSize*2; v += 2) {
8635: if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) {
8636: PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof;
8638: rc = rStar[v];
8639: PetscSectionGetDof(coordSectionNew, rc, &rcdof);
8640: if (!rcdof) continue;
8641: PetscSectionGetOffset(coordSectionNew, rc, &coff);
8642: DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);
8643: for (p = 0, lid = 0; p < closureSize*2; p += 2) {
8644: if (cone[p] == newv) {
8645: for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d];
8646: break;
8647: }
8648: if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++;
8649: }
8650: if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8651: DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);
8652: }
8653: }
8654: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8655: }
8656: }
8657: case REFINER_SIMPLEX_2D:
8658: case REFINER_HYBRID_SIMPLEX_2D:
8659: case REFINER_SIMPLEX_3D:
8660: case REFINER_HYBRID_SIMPLEX_3D:
8661: /* Edge vertices have the average of endpoint coordinates */
8662: for (e = eStart; e < eMax; ++e) {
8663: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
8664: const PetscInt *cone;
8665: PetscInt coneSize, offA, offB, offnew, d;
8667: DMPlexGetConeSize(dm, e, &coneSize);
8668: if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize);
8669: DMPlexGetCone(dm, e, &cone);
8670: if (localize) {
8671: PetscInt coff, toffA = -1, toffB = -1, voffA, voffB;
8672: PetscInt *eStar = NULL, eStarSize;
8673: PetscInt *rStar = NULL, rStarSize;
8674: PetscBool cellfound = PETSC_FALSE;
8676: offA = offB = -1;
8677: PetscSectionGetOffset(coordSection, cone[0], &voffA);
8678: PetscSectionGetOffset(coordSection, cone[1], &voffB);
8679: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);
8680: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8681: for (v = 0; v < eStarSize*2; v += 2) {
8682: if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) {
8683: PetscScalar coordsNewAux[3];
8684: PetscInt *cellCone = NULL;
8685: PetscInt cellClosureSize, s, cv, cdof;
8686: PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE;
8687: const PetscInt cell = eStar[v];
8689: PetscSectionGetDof(coordSection, cell, &cdof);
8690: if (!cdof) {
8691: /* Found a valid edge for the "vertex" part of the Section */
8692: offA = voffA;
8693: offB = voffB;
8694: cellfound = PETSC_TRUE;
8695: } else {
8696: PetscSectionGetOffset(coordSection, cell, &coff);
8697: DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8698: for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) {
8699: const PetscInt point = cellCone[s];
8700: if ((point >= vStart) && (point < vEnd)) {
8701: if (point == cone[0]) toffA = spaceDim*cv + coff;
8702: else if (point == cone[1]) toffB = spaceDim*cv + coff;
8703: cv++;
8704: }
8705: }
8706: DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);
8707: for (d = 0; d < spaceDim; ++d) {
8708: coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]);
8709: if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE;
8710: if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE;
8711: }
8712: /* Found a valid edge for the "vertex" part of the Section */
8713: if (!cellfound && (locvA || locvB)) {
8714: cellfound = PETSC_TRUE;
8715: offA = toffA;
8716: offB = toffB;
8717: }
8718: }
8720: /* Localize new coordinates on each refined cell */
8721: for (s = 0; s < rStarSize*2; s += 2) {
8722: if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) {
8723: PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof;
8724: const PetscInt rcell = rStar[s];
8726: PetscSectionGetDof(coordSectionNew, rcell, &rcdof);
8727: if (!rcdof) continue;
8728: PetscSectionGetOffset(coordSectionNew, rcell, &coff);
8729: DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8730: for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
8731: if (rcone[p] == newv) {
8732: for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d];
8733: break;
8734: }
8735: if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
8736: }
8737: DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);
8738: if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8739: }
8740: }
8741: }
8742: }
8743: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);
8744: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8745: if (!cellfound) {
8746: /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */
8747: needcoords = PETSC_TRUE;
8748: }
8749: } else {
8750: PetscSectionGetOffset(coordSection, cone[0], &offA);
8751: PetscSectionGetOffset(coordSection, cone[1], &offB);
8752: }
8753: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8754: if (offA != -1 && offB != -1) {
8755: DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);
8756: for (d = 0; d < spaceDim; ++d) {
8757: coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
8758: }
8759: } else {
8760: for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
8761: }
8762: }
8763: /* Old vertices have the same coordinates */
8764: for (v = vStart; v < vEnd; ++v) {
8765: const PetscInt newv = vStartNew + (v - vStart);
8766: PetscInt off, offnew, d;
8768: PetscSectionGetOffset(coordSection, v, &off);
8769: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
8770: for (d = 0; d < spaceDim; ++d) {
8771: coordsNew[offnew+d] = coords[off+d];
8772: }
8774: /* Localize new coordinates on each refined cell */
8775: if (localize) {
8776: PetscInt p;
8777: PetscInt *rStar = NULL, rStarSize;
8779: DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8780: for (p = 0; p < rStarSize*2; p += 2) {
8781: if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) {
8782: PetscScalar ocoords[3];
8783: PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof;
8785: c = rStar[p];
8786: oc = parentId[c-cStartNew];
8787: PetscSectionGetDof(coordSectionNew, c, &cdof);
8788: if (!cdof) continue;
8789: PetscSectionGetDof(coordSection, oc, &cdof);
8790: if (!cdof) continue;
8791: PetscSectionGetOffset(coordSection, oc, &coff);
8792: DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);
8793: for (s = 0, lid = 0; s < closureSize*2; s += 2) {
8794: if (cone[s] == v) {
8795: for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d];
8796: break;
8797: }
8798: if (cone[s] >= vStart && cone[s] < vEnd) lid++;
8799: }
8800: if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D",v);
8801: DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);
8803: PetscSectionGetOffset(coordSectionNew, c, &coff);
8804: DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8805: for (s = 0, lid = 0; s < closureSize*2; s += 2) {
8806: if (cone[s] == newv) {
8807: for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d];
8808: break;
8809: }
8810: if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++;
8811: }
8812: if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv);
8813: DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);
8814: }
8815: }
8816: DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);
8817: }
8818: }
8819: break;
8820: default:
8821: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
8822: }
8823: VecRestoreArray(coordinates, &coords);
8824: VecRestoreArray(coordinatesNew, &coordsNew);
8825: DMSetCoordinatesLocal(rdm, coordinatesNew);
8827: /* Final reduction (if needed) if we are localizing */
8828: if (localize) {
8829: PetscBool gred;
8831: MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));
8832: if (gred) {
8833: DM cdm;
8834: Vec aux;
8835: PetscSF sf;
8836: const PetscScalar *lArray;
8837: PetscScalar *gArray;
8838: #if defined(PETSC_USE_COMPLEX)
8839: PetscInt i, ln, gn;
8840: PetscReal *lrArray;
8841: PetscReal *grArray;
8842: #endif
8844: DMGetCoordinateDM(rdm, &cdm);
8845: DMCreateGlobalVector(cdm, &aux);
8846: DMGetSectionSF(cdm, &sf);
8847: VecGetArrayRead(coordinatesNew, &lArray);
8848: VecSet(aux, PETSC_MIN_REAL);
8849: VecGetArray(aux, &gArray);
8850: #if defined(PETSC_USE_COMPLEX)
8851: VecGetLocalSize(aux, &gn);
8852: VecGetLocalSize(coordinatesNew, &ln);
8853: PetscMalloc2(ln,&lrArray,gn,&grArray);
8854: for (i=0;i<ln;i++) lrArray[i] = PetscRealPart(lArray[i]);
8855: for (i=0;i<gn;i++) grArray[i] = PetscRealPart(gArray[i]);
8856: PetscSFReduceBegin(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);
8857: PetscSFReduceEnd(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);
8858: for (i=0;i<gn;i++) gArray[i] = grArray[i];
8859: PetscFree2(lrArray,grArray);
8860: #else
8861: PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);
8862: PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);
8863: #endif
8864: VecRestoreArrayRead(coordinatesNew, &lArray);
8865: VecRestoreArray(aux, &gArray);
8866: DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);
8867: DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);
8868: VecDestroy(&aux);
8869: }
8870: }
8871: VecDestroy(&coordinatesNew);
8872: PetscSectionDestroy(&coordSectionNew);
8873: PetscFree(parentId);
8874: return(0);
8875: }
8877: /*@
8878: DMPlexCreateProcessSF - Create an SF which just has process connectivity
8880: Collective on dm
8882: Input Parameters:
8883: + dm - The DM
8884: - sfPoint - The PetscSF which encodes point connectivity
8886: Output Parameters:
8887: + processRanks - A list of process neighbors, or NULL
8888: - sfProcess - An SF encoding the process connectivity, or NULL
8890: Level: developer
8892: .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
8893: @*/
8894: PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
8895: {
8896: PetscInt numRoots, numLeaves, l;
8897: const PetscInt *localPoints;
8898: const PetscSFNode *remotePoints;
8899: PetscInt *localPointsNew;
8900: PetscSFNode *remotePointsNew;
8901: PetscInt *ranks, *ranksNew;
8902: PetscMPIInt size;
8903: PetscErrorCode ierr;
8910: MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);
8911: PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);
8912: PetscMalloc1(numLeaves, &ranks);
8913: for (l = 0; l < numLeaves; ++l) {
8914: ranks[l] = remotePoints[l].rank;
8915: }
8916: PetscSortRemoveDupsInt(&numLeaves, ranks);
8917: PetscMalloc1(numLeaves, &ranksNew);
8918: PetscMalloc1(numLeaves, &localPointsNew);
8919: PetscMalloc1(numLeaves, &remotePointsNew);
8920: for (l = 0; l < numLeaves; ++l) {
8921: ranksNew[l] = ranks[l];
8922: localPointsNew[l] = l;
8923: remotePointsNew[l].index = 0;
8924: remotePointsNew[l].rank = ranksNew[l];
8925: }
8926: PetscFree(ranks);
8927: if (processRanks) {ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);}
8928: else {PetscFree(ranksNew);}
8929: if (sfProcess) {
8930: PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);
8931: PetscObjectSetName((PetscObject) *sfProcess, "Process SF");
8932: PetscSFSetFromOptions(*sfProcess);
8933: PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);
8934: }
8935: return(0);
8936: }
8938: static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
8939: {
8940: PetscSF sf, sfNew, sfProcess;
8941: IS processRanks;
8942: MPI_Datatype depthType;
8943: PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m;
8944: const PetscInt *localPoints, *neighbors;
8945: const PetscSFNode *remotePoints;
8946: PetscInt *localPointsNew;
8947: PetscSFNode *remotePointsNew;
8948: PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
8949: PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
8950: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
8951: PetscErrorCode ierr;
8954: DMPlexGetChart(rdm, &pStartNew, &pEndNew);
8955: DMPlexGetDepth(dm, &ldepth);
8956: MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));
8957: if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %D != %D", ldepth, depth);
8958: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
8959: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
8960: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
8961: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
8962: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
8963: cMax = cMax < 0 ? cEnd : cMax;
8964: fMax = fMax < 0 ? fEnd : fMax;
8965: eMax = eMax < 0 ? eEnd : eMax;
8966: if (refiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
8967: DMGetPointSF(dm, &sf);
8968: DMGetPointSF(rdm, &sfNew);
8969: /* Calculate size of new SF */
8970: PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);
8971: if (numRoots < 0) return(0);
8972: for (l = 0; l < numLeaves; ++l) {
8973: const PetscInt p = localPoints[l];
8975: switch (refiner) {
8976: case REFINER_SIMPLEX_1D:
8977: if ((p >= vStart) && (p < vEnd)) {
8978: /* Interior vertices stay the same */
8979: ++numLeavesNew;
8980: } else if ((p >= cStart && p < cMax)) {
8981: /* Interior cells add new cells and interior vertices */
8982: numLeavesNew += 2 + 1;
8983: }
8984: break;
8985: case REFINER_SIMPLEX_2D:
8986: case REFINER_HYBRID_SIMPLEX_2D:
8987: if ((p >= vStart) && (p < vEnd)) {
8988: /* Interior vertices stay the same */
8989: ++numLeavesNew;
8990: } else if ((p >= fStart) && (p < fMax)) {
8991: /* Interior faces add new faces and vertex */
8992: numLeavesNew += 2 + 1;
8993: } else if ((p >= fMax) && (p < fEnd)) {
8994: /* Hybrid faces stay the same */
8995: ++numLeavesNew;
8996: } else if ((p >= cStart) && (p < cMax)) {
8997: /* Interior cells add new cells and interior faces */
8998: numLeavesNew += 4 + 3;
8999: } else if ((p >= cMax) && (p < cEnd)) {
9000: /* Hybrid cells add new cells and hybrid face */
9001: numLeavesNew += 2 + 1;
9002: }
9003: break;
9004: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9005: case REFINER_SIMPLEX_TO_HEX_2D:
9006: if ((p >= vStart) && (p < vEnd)) {
9007: /* Interior vertices stay the same */
9008: ++numLeavesNew;
9009: } else if ((p >= fStart) && (p < fEnd)) {
9010: /* Interior faces add new faces and vertex */
9011: numLeavesNew += 2 + 1;
9012: } else if ((p >= cStart) && (p < cMax)) {
9013: /* Interior cells add new cells, interior faces, and vertex */
9014: numLeavesNew += 3 + 3 + 1;
9015: } else if ((p >= cMax) && (p < cEnd)) {
9016: /* Hybrid cells add new cells, interior faces, and vertex */
9017: numLeavesNew += 4 + 4 + 1;
9018: }
9019: break;
9020: case REFINER_HEX_2D:
9021: case REFINER_HYBRID_HEX_2D:
9022: if ((p >= vStart) && (p < vEnd)) {
9023: /* Interior vertices stay the same */
9024: ++numLeavesNew;
9025: } else if ((p >= fStart) && (p < fMax)) {
9026: /* Interior faces add new faces and vertex */
9027: numLeavesNew += 2 + 1;
9028: } else if ((p >= fMax) && (p < fEnd)) {
9029: /* Hybrid faces stay the same */
9030: ++numLeavesNew;
9031: } else if ((p >= cStart) && (p < cMax)) {
9032: /* Interior cells add new cells, interior faces, and vertex */
9033: numLeavesNew += 4 + 4 + 1;
9034: } else if ((p >= cMax) && (p < cEnd)) {
9035: /* Hybrid cells add new cells and hybrid face */
9036: numLeavesNew += 2 + 1;
9037: }
9038: break;
9039: case REFINER_SIMPLEX_3D:
9040: case REFINER_HYBRID_SIMPLEX_3D:
9041: if ((p >= vStart) && (p < vEnd)) {
9042: /* Interior vertices stay the same */
9043: ++numLeavesNew;
9044: } else if ((p >= eStart) && (p < eMax)) {
9045: /* Interior edges add new edges and vertex */
9046: numLeavesNew += 2 + 1;
9047: } else if ((p >= eMax) && (p < eEnd)) {
9048: /* Hybrid edges stay the same */
9049: ++numLeavesNew;
9050: } else if ((p >= fStart) && (p < fMax)) {
9051: /* Interior faces add new faces and edges */
9052: numLeavesNew += 4 + 3;
9053: } else if ((p >= fMax) && (p < fEnd)) {
9054: /* Hybrid faces add new faces and edges */
9055: numLeavesNew += 2 + 1;
9056: } else if ((p >= cStart) && (p < cMax)) {
9057: /* Interior cells add new cells, faces, and edges */
9058: numLeavesNew += 8 + 8 + 1;
9059: } else if ((p >= cMax) && (p < cEnd)) {
9060: /* Hybrid cells add new cells and faces */
9061: numLeavesNew += 4 + 3;
9062: }
9063: break;
9064: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9065: case REFINER_SIMPLEX_TO_HEX_3D:
9066: if ((p >= vStart) && (p < vEnd)) {
9067: /* Interior vertices stay the same */
9068: ++numLeavesNew;
9069: } else if ((p >= eStart) && (p < eMax)) {
9070: /* Interior edges add new edges and vertex */
9071: numLeavesNew += 2 + 1;
9072: } else if ((p >= eMax) && (p < eEnd)) {
9073: /* Hybrid edges stay the same */
9074: ++numLeavesNew;
9075: } else if ((p >= fStart) && (p < fMax)) {
9076: /* Interior faces add new faces, edges and a vertex */
9077: numLeavesNew += 3 + 3 + 1;
9078: } else if ((p >= fMax) && (p < fEnd)) {
9079: /* Hybrid faces add new faces and an edge */
9080: numLeavesNew += 2 + 1;
9081: } else if ((p >= cStart) && (p < cMax)) {
9082: /* Interior cells add new cells, faces, edges and a vertex */
9083: numLeavesNew += 4 + 6 + 4 + 1;
9084: } else if ((p >= cMax) && (p < cEnd)) {
9085: /* Hybrid cells add new cells, faces and an edge */
9086: numLeavesNew += 3 + 3 + 1;
9087: }
9088: break;
9089: case REFINER_HEX_3D:
9090: case REFINER_HYBRID_HEX_3D:
9091: if ((p >= vStart) && (p < vEnd)) {
9092: /* Old vertices stay the same */
9093: ++numLeavesNew;
9094: } else if ((p >= eStart) && (p < eMax)) {
9095: /* Interior edges add new edges, and vertex */
9096: numLeavesNew += 2 + 1;
9097: } else if ((p >= eMax) && (p < eEnd)) {
9098: /* Hybrid edges stay the same */
9099: ++numLeavesNew;
9100: } else if ((p >= fStart) && (p < fMax)) {
9101: /* Interior faces add new faces, edges, and vertex */
9102: numLeavesNew += 4 + 4 + 1;
9103: } else if ((p >= fMax) && (p < fEnd)) {
9104: /* Hybrid faces add new faces and edges */
9105: numLeavesNew += 2 + 1;
9106: } else if ((p >= cStart) && (p < cMax)) {
9107: /* Interior cells add new cells, faces, edges, and vertex */
9108: numLeavesNew += 8 + 12 + 6 + 1;
9109: } else if ((p >= cStart) && (p < cEnd)) {
9110: /* Hybrid cells add new cells, faces, and edges */
9111: numLeavesNew += 4 + 4 + 1;
9112: }
9113: break;
9114: default:
9115: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
9116: }
9117: }
9118: /* Communicate depthSizes for each remote rank */
9119: DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);
9120: ISGetLocalSize(processRanks, &numNeighbors);
9121: PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);
9122: PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);
9123: MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);
9124: MPI_Type_commit(&depthType);
9125: PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);
9126: PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);
9127: for (n = 0; n < numNeighbors; ++n) {
9128: GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);
9129: }
9130: depthSizeOld[depth] = cMax;
9131: depthSizeOld[0] = vMax;
9132: depthSizeOld[depth-1] = fMax;
9133: depthSizeOld[1] = eMax;
9135: PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);
9136: PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);
9138: depthSizeOld[depth] = cEnd - cStart;
9139: depthSizeOld[0] = vEnd - vStart;
9140: depthSizeOld[depth-1] = fEnd - fStart;
9141: depthSizeOld[1] = eEnd - eStart;
9143: PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);
9144: PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);
9145: for (n = 0; n < numNeighbors; ++n) {
9146: GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);
9147: rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth];
9148: 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];
9149: rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1];
9150: }
9151: MPI_Type_free(&depthType);
9152: PetscSFDestroy(&sfProcess);
9153: /* Calculate new point SF */
9154: PetscMalloc1(numLeavesNew, &localPointsNew);
9155: PetscMalloc1(numLeavesNew, &remotePointsNew);
9156: ISGetIndices(processRanks, &neighbors);
9157: for (l = 0, m = 0; l < numLeaves; ++l) {
9158: PetscInt p = localPoints[l];
9159: PetscInt rp = remotePoints[l].index, n;
9160: PetscMPIInt rrank = remotePoints[l].rank;
9162: PetscFindInt(rrank, numNeighbors, neighbors, &n);
9163: if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rrank);
9164: switch (refiner) {
9165: case REFINER_SIMPLEX_1D:
9166: if ((p >= vStart) && (p < vEnd)) {
9167: /* Old vertices stay the same */
9168: localPointsNew[m] = vStartNew + (p - vStart);
9169: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9170: remotePointsNew[m].rank = rrank;
9171: ++m;
9172: } else if ((p >= cStart) && (p < cMax)) {
9173: /* Old interior cells add new cells and vertex */
9174: for (r = 0; r < 2; ++r, ++m) {
9175: localPointsNew[m] = cStartNew + (p - cStart)*2 + r;
9176: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r;
9177: remotePointsNew[m].rank = rrank;
9178: }
9179: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart);
9180: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]);
9181: remotePointsNew[m].rank = rrank;
9182: ++m;
9183: }
9184: break;
9185: case REFINER_SIMPLEX_2D:
9186: case REFINER_HYBRID_SIMPLEX_2D:
9187: if ((p >= vStart) && (p < vEnd)) {
9188: /* Old vertices stay the same */
9189: localPointsNew[m] = vStartNew + (p - vStart);
9190: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9191: remotePointsNew[m].rank = rrank;
9192: ++m;
9193: } else if ((p >= fStart) && (p < fMax)) {
9194: /* Old interior faces add new faces and vertex */
9195: for (r = 0; r < 2; ++r, ++m) {
9196: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
9197: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
9198: remotePointsNew[m].rank = rrank;
9199: }
9200: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
9201: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
9202: remotePointsNew[m].rank = rrank;
9203: ++m;
9204: } else if ((p >= fMax) && (p < fEnd)) {
9205: /* Old hybrid faces stay the same */
9206: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax);
9207: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
9208: remotePointsNew[m].rank = rrank;
9209: ++m;
9210: } else if ((p >= cStart) && (p < cMax)) {
9211: /* Old interior cells add new cells and interior faces */
9212: for (r = 0; r < 4; ++r, ++m) {
9213: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9214: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9215: remotePointsNew[m].rank = rrank;
9216: }
9217: for (r = 0; r < 3; ++r, ++m) {
9218: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r;
9219: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
9220: remotePointsNew[m].rank = rrank;
9221: }
9222: } else if ((p >= cMax) && (p < cEnd)) {
9223: /* Old hybrid cells add new cells and hybrid face */
9224: for (r = 0; r < 2; ++r, ++m) {
9225: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9226: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9227: remotePointsNew[m].rank = rrank;
9228: }
9229: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
9230: 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]);
9231: remotePointsNew[m].rank = rrank;
9232: ++m;
9233: }
9234: break;
9235: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9236: case REFINER_SIMPLEX_TO_HEX_2D:
9237: if ((p >= vStart) && (p < vEnd)) {
9238: /* Old vertices stay the same */
9239: localPointsNew[m] = vStartNew + (p - vStart);
9240: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9241: remotePointsNew[m].rank = rrank;
9242: ++m;
9243: } else if ((p >= fStart) && (p < fEnd)) {
9244: /* Old interior faces add new faces and vertex */
9245: for (r = 0; r < 2; ++r, ++m) {
9246: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
9247: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
9248: remotePointsNew[m].rank = rrank;
9249: }
9250: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
9251: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
9252: remotePointsNew[m].rank = rrank;
9253: ++m;
9254: } else if ((p >= cStart) && (p < cMax)) {
9255: /* Old interior cells add new cells, interior faces, and a vertex */
9256: for (r = 0; r < 3; ++r, ++m) {
9257: localPointsNew[m] = cStartNew + (p - cStart)*3 + r;
9258: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r;
9259: remotePointsNew[m].rank = rrank;
9260: }
9261: for (r = 0; r < 3; ++r, ++m) {
9262: localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9263: remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
9264: remotePointsNew[m].rank = rrank;
9265: }
9266: localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9267: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
9268: remotePointsNew[m].rank = rrank;
9269: ++m;
9270: } else if ((p >= cMax) && (p < cEnd)) {
9271: /* Old interior hybrid cells add new cells, interior faces, and a vertex */
9272: for (r = 0; r < 4; ++r, ++m) {
9273: localPointsNew[m] = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r;
9274: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
9275: remotePointsNew[m].rank = rrank;
9276: }
9277: for (r = 0; r < 4; ++r, ++m) {
9278: localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r;
9279: 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;
9280: remotePointsNew[m].rank = rrank;
9281: }
9282: localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9283: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
9284: remotePointsNew[m].rank = rrank;
9285: ++m;
9286: }
9287: break;
9288: case REFINER_HEX_2D:
9289: case REFINER_HYBRID_HEX_2D:
9290: if ((p >= vStart) && (p < vEnd)) {
9291: /* Old vertices stay the same */
9292: localPointsNew[m] = vStartNew + (p - vStart);
9293: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9294: remotePointsNew[m].rank = rrank;
9295: ++m;
9296: } else if ((p >= fStart) && (p < fMax)) {
9297: /* Old interior faces add new faces and vertex */
9298: for (r = 0; r < 2; ++r, ++m) {
9299: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
9300: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
9301: remotePointsNew[m].rank = rrank;
9302: }
9303: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
9304: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
9305: remotePointsNew[m].rank = rrank;
9306: ++m;
9307: } else if ((p >= fMax) && (p < fEnd)) {
9308: /* Old hybrid faces stay the same */
9309: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax);
9310: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
9311: remotePointsNew[m].rank = rrank;
9312: ++m;
9313: } else if ((p >= cStart) && (p < cMax)) {
9314: /* Old interior cells add new cells, interior faces, and vertex */
9315: for (r = 0; r < 4; ++r, ++m) {
9316: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9317: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9318: remotePointsNew[m].rank = rrank;
9319: }
9320: for (r = 0; r < 4; ++r, ++m) {
9321: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r;
9322: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
9323: remotePointsNew[m].rank = rrank;
9324: }
9325: localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart);
9326: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
9327: remotePointsNew[m].rank = rrank;
9328: ++m;
9329: } else if ((p >= cStart) && (p < cMax)) {
9330: /* Old hybrid cells add new cells and hybrid face */
9331: for (r = 0; r < 2; ++r, ++m) {
9332: localPointsNew[m] = cStartNew + (p - cStart)*4 + r; /* TODO: is this a bug? */
9333: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; /* TODO: is this a bug? */
9334: remotePointsNew[m].rank = rrank;
9335: }
9336: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
9337: 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]);
9338: remotePointsNew[m].rank = rrank;
9339: ++m;
9340: }
9341: break;
9342: case REFINER_SIMPLEX_3D:
9343: case REFINER_HYBRID_SIMPLEX_3D:
9344: if ((p >= vStart) && (p < vEnd)) {
9345: /* Interior vertices stay the same */
9346: localPointsNew[m] = vStartNew + (p - vStart);
9347: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9348: remotePointsNew[m].rank = rrank;
9349: ++m;
9350: } else if ((p >= eStart) && (p < eMax)) {
9351: /* Interior edges add new edges and vertex */
9352: for (r = 0; r < 2; ++r, ++m) {
9353: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
9354: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
9355: remotePointsNew[m].rank = rrank;
9356: }
9357: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
9358: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
9359: remotePointsNew[m].rank = rrank;
9360: ++m;
9361: } else if ((p >= eMax) && (p < eEnd)) {
9362: /* Hybrid edges stay the same */
9363: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
9364: 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]);
9365: remotePointsNew[m].rank = rrank;
9366: ++m;
9367: } else if ((p >= fStart) && (p < fMax)) {
9368: /* Interior faces add new faces and edges */
9369: for (r = 0; r < 4; ++r, ++m) {
9370: localPointsNew[m] = fStartNew + (p - fStart)*4 + r;
9371: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
9372: remotePointsNew[m].rank = rrank;
9373: }
9374: for (r = 0; r < 3; ++r, ++m) {
9375: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
9376: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
9377: remotePointsNew[m].rank = rrank;
9378: }
9379: } else if ((p >= fMax) && (p < fEnd)) {
9380: /* Hybrid faces add new faces and edges */
9381: for (r = 0; r < 2; ++r, ++m) {
9382: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
9383: 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;
9384: remotePointsNew[m].rank = rrank;
9385: }
9386: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax);
9387: 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]);
9388: remotePointsNew[m].rank = rrank;
9389: ++m;
9390: } else if ((p >= cStart) && (p < cMax)) {
9391: /* Interior cells add new cells, faces, and edges */
9392: for (r = 0; r < 8; ++r, ++m) {
9393: localPointsNew[m] = cStartNew + (p - cStart)*8 + r;
9394: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
9395: remotePointsNew[m].rank = rrank;
9396: }
9397: for (r = 0; r < 8; ++r, ++m) {
9398: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
9399: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
9400: remotePointsNew[m].rank = rrank;
9401: }
9402: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0;
9403: 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;
9404: remotePointsNew[m].rank = rrank;
9405: ++m;
9406: } else if ((p >= cMax) && (p < cEnd)) {
9407: /* Hybrid cells add new cells and faces */
9408: for (r = 0; r < 4; ++r, ++m) {
9409: localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
9410: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
9411: remotePointsNew[m].rank = rrank;
9412: }
9413: for (r = 0; r < 3; ++r, ++m) {
9414: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
9415: 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;
9416: remotePointsNew[m].rank = rrank;
9417: }
9418: }
9419: break;
9420: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9421: case REFINER_SIMPLEX_TO_HEX_3D:
9422: if ((p >= vStart) && (p < vEnd)) {
9423: /* Interior vertices stay the same */
9424: localPointsNew[m] = vStartNew + (p - vStart);
9425: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9426: remotePointsNew[m].rank = rrank;
9427: ++m;
9428: } else if ((p >= eStart) && (p < eMax)) {
9429: /* Interior edges add new edges and vertex */
9430: for (r = 0; r < 2; ++r, ++m) {
9431: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
9432: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
9433: remotePointsNew[m].rank = rrank;
9434: }
9435: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
9436: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
9437: remotePointsNew[m].rank = rrank;
9438: ++m;
9439: } else if ((p >= eMax) && (p < eEnd)) {
9440: /* Hybrid edges stay the same */
9441: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (p - eMax);
9442: 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]);
9443: remotePointsNew[m].rank = rrank;
9444: ++m;
9445: } else if ((p >= fStart) && (p < fMax)) {
9446: /* Interior faces add new faces, edges and a vertex */
9447: for (r = 0; r < 3; ++r, ++m) {
9448: localPointsNew[m] = fStartNew + (p - fStart)*3 + r;
9449: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r;
9450: remotePointsNew[m].rank = rrank;
9451: }
9452: for (r = 0; r < 3; ++r, ++m) {
9453: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
9454: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
9455: remotePointsNew[m].rank = rrank;
9456: }
9457: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
9458: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
9459: remotePointsNew[m].rank = rrank;
9460: ++m;
9461: } else if ((p >= fMax) && (p < fEnd)) {
9462: /* Interior hybrid faces add new faces and an edge */
9463: for (r = 0; r < 2; ++r, ++m) {
9464: localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r;
9465: 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;
9466: remotePointsNew[m].rank = rrank;
9467: }
9468: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax);
9469: 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]);
9470: remotePointsNew[m].rank = rrank;
9471: ++m;
9472: } else if ((p >= cStart) && (p < cMax)) {
9473: /* Interior cells add new cells, faces, edges, and a vertex */
9474: for (r = 0; r < 4; ++r, ++m) {
9475: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
9476: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
9477: remotePointsNew[m].rank = rrank;
9478: }
9479: for (r = 0; r < 6; ++r, ++m) {
9480: localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r;
9481: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*6 + r;
9482: remotePointsNew[m].rank = rrank;
9483: }
9484: for (r = 0; r < 4; ++r, ++m) {
9485: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r;
9486: 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;
9487: remotePointsNew[m].rank = rrank;
9488: }
9489: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
9490: 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]);
9491: remotePointsNew[m].rank = rrank;
9492: ++m;
9493: } else if ((p >= cMax) && (p < cEnd)) {
9494: /* Interior hybrid cells add new cells, faces and an edge */
9495: for (r = 0; r < 3; ++r, ++m) {
9496: localPointsNew[m] = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r;
9497: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r;
9498: remotePointsNew[m].rank = rrank;
9499: }
9500: for (r = 0; r < 3; ++r, ++m) {
9501: localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
9502: 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;
9503: remotePointsNew[m].rank = rrank;
9504: }
9505: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax);
9506: 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]);
9507: remotePointsNew[m].rank = rrank;
9508: ++m;
9509: }
9510: break;
9511: case REFINER_HEX_3D:
9512: case REFINER_HYBRID_HEX_3D:
9513: if ((p >= vStart) && (p < vEnd)) {
9514: /* Interior vertices stay the same */
9515: localPointsNew[m] = vStartNew + (p - vStart);
9516: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
9517: remotePointsNew[m].rank = rrank;
9518: ++m;
9519: } else if ((p >= eStart) && (p < eMax)) {
9520: /* Interior edges add new edges and vertex */
9521: for (r = 0; r < 2; ++r, ++m) {
9522: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
9523: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
9524: remotePointsNew[m].rank = rrank;
9525: }
9526: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
9527: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
9528: remotePointsNew[m].rank = rrank;
9529: ++m;
9530: } else if ((p >= eMax) && (p < eEnd)) {
9531: /* Hybrid edges stay the same */
9532: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
9533: 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]);
9534: remotePointsNew[m].rank = rrank;
9535: ++m;
9536: } else if ((p >= fStart) && (p < fMax)) {
9537: /* Interior faces add new faces, edges, and vertex */
9538: for (r = 0; r < 4; ++r, ++m) {
9539: localPointsNew[m] = fStartNew + (p - fStart)*4 + r;
9540: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
9541: remotePointsNew[m].rank = rrank;
9542: }
9543: for (r = 0; r < 4; ++r, ++m) {
9544: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
9545: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
9546: remotePointsNew[m].rank = rrank;
9547: }
9548: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
9549: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
9550: remotePointsNew[m].rank = rrank;
9551: ++m;
9552: } else if ((p >= fMax) && (p < fEnd)) {
9553: /* Hybrid faces add new faces and edges */
9554: for (r = 0; r < 2; ++r, ++m) {
9555: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
9556: 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;
9557: remotePointsNew[m].rank = rrank;
9558: }
9559: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax);
9560: 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]);
9561: remotePointsNew[m].rank = rrank;
9562: ++m;
9563: } else if ((p >= cStart) && (p < cMax)) {
9564: /* Interior cells add new cells, faces, edges, and vertex */
9565: for (r = 0; r < 8; ++r, ++m) {
9566: localPointsNew[m] = cStartNew + (p - cStart)*8 + r;
9567: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
9568: remotePointsNew[m].rank = rrank;
9569: }
9570: for (r = 0; r < 12; ++r, ++m) {
9571: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
9572: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
9573: remotePointsNew[m].rank = rrank;
9574: }
9575: for (r = 0; r < 6; ++r, ++m) {
9576: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
9577: 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;
9578: remotePointsNew[m].rank = rrank;
9579: }
9580: for (r = 0; r < 1; ++r, ++m) {
9581: localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r;
9582: remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r;
9583: remotePointsNew[m].rank = rrank;
9584: }
9585: } else if ((p >= cMax) && (p < cEnd)) {
9586: /* Hybrid cells add new cells, faces, and edges */
9587: for (r = 0; r < 4; ++r, ++m) {
9588: localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
9589: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
9590: remotePointsNew[m].rank = rrank;
9591: }
9592: for (r = 0; r < 4; ++r, ++m) {
9593: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
9594: 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;
9595: remotePointsNew[m].rank = rrank;
9596: }
9597: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax);
9598: 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]);
9599: remotePointsNew[m].rank = rrank;
9600: ++m;
9601: }
9602: break;
9603: default:
9604: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
9605: }
9606: }
9607: if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew);
9608: ISRestoreIndices(processRanks, &neighbors);
9609: ISDestroy(&processRanks);
9610: {
9611: PetscSFNode *rp, *rtmp;
9612: PetscInt *lp, *idx, *ltmp, i;
9614: /* SF needs sorted leaves to correct calculate Gather */
9615: PetscMalloc1(numLeavesNew,&idx);
9616: PetscMalloc1(numLeavesNew, &lp);
9617: PetscMalloc1(numLeavesNew, &rp);
9618: for (i = 0; i < numLeavesNew; ++i) {
9619: 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);
9620: idx[i] = i;
9621: }
9622: PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);
9623: for (i = 0; i < numLeavesNew; ++i) {
9624: lp[i] = localPointsNew[idx[i]];
9625: rp[i] = remotePointsNew[idx[i]];
9626: }
9627: ltmp = localPointsNew;
9628: localPointsNew = lp;
9629: rtmp = remotePointsNew;
9630: remotePointsNew = rp;
9631: PetscFree(idx);
9632: PetscFree(ltmp);
9633: PetscFree(rtmp);
9634: }
9635: PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);
9636: PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);
9637: PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);
9638: return(0);
9639: }
9641: static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
9642: {
9643: PetscInt numLabels, l;
9644: PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
9645: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
9649: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
9650: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
9651: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
9652: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
9653: DMPlexGetDepth(dm, &depth);
9654: if (refiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
9655: DMGetNumLabels(dm, &numLabels);
9656: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
9657: switch (refiner) {
9658: case REFINER_NOOP:
9659: case REFINER_SIMPLEX_1D:
9660: case REFINER_SIMPLEX_2D:
9661: case REFINER_SIMPLEX_TO_HEX_2D:
9662: case REFINER_HEX_2D:
9663: case REFINER_SIMPLEX_3D:
9664: case REFINER_HEX_3D:
9665: case REFINER_SIMPLEX_TO_HEX_3D:
9666: break;
9667: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9668: case REFINER_HYBRID_SIMPLEX_3D:
9669: case REFINER_HYBRID_HEX_3D:
9670: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
9671: case REFINER_HYBRID_SIMPLEX_2D:
9672: case REFINER_HYBRID_HEX_2D:
9673: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
9674: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9675: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
9676: break;
9677: default:
9678: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
9679: }
9680: cMax = cMax < 0 ? cEnd : cMax;
9681: fMax = fMax < 0 ? fEnd : fMax;
9682: eMax = eMax < 0 ? eEnd : eMax;
9683: for (l = 0; l < numLabels; ++l) {
9684: DMLabel label, labelNew;
9685: const char *lname;
9686: PetscBool isDepth;
9687: IS valueIS;
9688: const PetscInt *values;
9689: PetscInt defVal;
9690: PetscInt numValues, val;
9692: DMGetLabelName(dm, l, &lname);
9693: PetscStrcmp(lname, "depth", &isDepth);
9694: if (isDepth) continue;
9695: DMCreateLabel(rdm, lname);
9696: DMGetLabel(dm, lname, &label);
9697: DMGetLabel(rdm, lname, &labelNew);
9698: DMLabelGetDefaultValue(label,&defVal);
9699: DMLabelSetDefaultValue(labelNew,defVal);
9700: DMLabelGetValueIS(label, &valueIS);
9701: ISGetLocalSize(valueIS, &numValues);
9702: ISGetIndices(valueIS, &values);
9703: for (val = 0; val < numValues; ++val) {
9704: IS pointIS;
9705: const PetscInt *points;
9706: PetscInt numPoints, n;
9708: DMLabelGetStratumIS(label, values[val], &pointIS);
9709: ISGetLocalSize(pointIS, &numPoints);
9710: ISGetIndices(pointIS, &points);
9711: /* Ensure refined label is created with same number of strata as
9712: * original (even if no entries here). */
9713: DMLabelAddStratum(labelNew, values[val]);
9714: for (n = 0; n < numPoints; ++n) {
9715: const PetscInt p = points[n];
9716: switch (refiner) {
9717: case REFINER_SIMPLEX_1D:
9718: if ((p >= vStart) && (p < vEnd)) {
9719: /* Old vertices stay the same */
9720: newp = vStartNew + (p - vStart);
9721: DMLabelSetValue(labelNew, newp, values[val]);
9722: } else if ((p >= cStart) && (p < cEnd)) {
9723: /* Old cells add new cells and vertex */
9724: newp = vStartNew + (vEnd - vStart) + (p - cStart);
9725: DMLabelSetValue(labelNew, newp, values[val]);
9726: for (r = 0; r < 2; ++r) {
9727: newp = cStartNew + (p - cStart)*2 + r;
9728: DMLabelSetValue(labelNew, newp, values[val]);
9729: }
9730: }
9731: break;
9732: case REFINER_SIMPLEX_2D:
9733: if ((p >= vStart) && (p < vEnd)) {
9734: /* Old vertices stay the same */
9735: newp = vStartNew + (p - vStart);
9736: DMLabelSetValue(labelNew, newp, values[val]);
9737: } else if ((p >= fStart) && (p < fEnd)) {
9738: /* Old faces add new faces and vertex */
9739: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9740: DMLabelSetValue(labelNew, newp, values[val]);
9741: for (r = 0; r < 2; ++r) {
9742: newp = fStartNew + (p - fStart)*2 + r;
9743: DMLabelSetValue(labelNew, newp, values[val]);
9744: }
9745: } else if ((p >= cStart) && (p < cEnd)) {
9746: /* Old cells add new cells and interior faces */
9747: for (r = 0; r < 4; ++r) {
9748: newp = cStartNew + (p - cStart)*4 + r;
9749: DMLabelSetValue(labelNew, newp, values[val]);
9750: }
9751: for (r = 0; r < 3; ++r) {
9752: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9753: DMLabelSetValue(labelNew, newp, values[val]);
9754: }
9755: }
9756: break;
9757: case REFINER_HYBRID_SIMPLEX_TO_HEX_2D:
9758: case REFINER_SIMPLEX_TO_HEX_2D:
9759: if ((p >= vStart) && (p < vEnd)) {
9760: /* Old vertices stay the same */
9761: newp = vStartNew + (p - vStart);
9762: DMLabelSetValue(labelNew, newp, values[val]);
9763: } else if ((p >= fStart) && (p < fEnd)) {
9764: /* Old faces add new faces and vertex */
9765: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9766: DMLabelSetValue(labelNew, newp, values[val]);
9767: for (r = 0; r < 2; ++r) {
9768: newp = fStartNew + (p - fStart)*2 + r;
9769: DMLabelSetValue(labelNew, newp, values[val]);
9770: }
9771: } else if ((p >= cStart) && (p < cMax)) {
9772: /* Old cells add new cells, interior faces, and a vertex */
9773: for (r = 0; r < 3; ++r) {
9774: newp = cStartNew + (p - cStart)*3 + r;
9775: DMLabelSetValue(labelNew, newp, values[val]);
9776: }
9777: for (r = 0; r < 3; ++r) {
9778: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9779: DMLabelSetValue(labelNew, newp, values[val]);
9780: }
9781: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p;
9782: DMLabelSetValue(labelNew, newp, values[val]);
9783: } else if ((p >= cMax) && (p < cEnd)) {
9784: /* Old hybrid cells add new cells, interior faces, and a vertex */
9785: for (r = 0; r < 4; ++r) {
9786: newp = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r;
9787: DMLabelSetValue(labelNew, newp, values[val]);
9788: }
9789: for (r = 0; r < 4; ++r) {
9790: newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r;
9791: DMLabelSetValue(labelNew, newp, values[val]);
9792: }
9793: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p;
9794: DMLabelSetValue(labelNew, newp, values[val]);
9795: }
9796: break;
9797: case REFINER_HEX_2D:
9798: if ((p >= vStart) && (p < vEnd)) {
9799: /* Old vertices stay the same */
9800: newp = vStartNew + (p - vStart);
9801: DMLabelSetValue(labelNew, newp, values[val]);
9802: } else if ((p >= fStart) && (p < fEnd)) {
9803: /* Old faces add new faces and vertex */
9804: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9805: DMLabelSetValue(labelNew, newp, values[val]);
9806: for (r = 0; r < 2; ++r) {
9807: newp = fStartNew + (p - fStart)*2 + r;
9808: DMLabelSetValue(labelNew, newp, values[val]);
9809: }
9810: } else if ((p >= cStart) && (p < cEnd)) {
9811: /* Old cells add new cells and interior faces and vertex */
9812: for (r = 0; r < 4; ++r) {
9813: newp = cStartNew + (p - cStart)*4 + r;
9814: DMLabelSetValue(labelNew, newp, values[val]);
9815: }
9816: for (r = 0; r < 4; ++r) {
9817: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
9818: DMLabelSetValue(labelNew, newp, values[val]);
9819: }
9820: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9821: DMLabelSetValue(labelNew, newp, values[val]);
9822: }
9823: break;
9824: case REFINER_HYBRID_SIMPLEX_2D:
9825: if ((p >= vStart) && (p < vEnd)) {
9826: /* Old vertices stay the same */
9827: newp = vStartNew + (p - vStart);
9828: DMLabelSetValue(labelNew, newp, values[val]);
9829: } else if ((p >= fStart) && (p < fMax)) {
9830: /* Old interior faces add new faces and vertex */
9831: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9832: DMLabelSetValue(labelNew, newp, values[val]);
9833: for (r = 0; r < 2; ++r) {
9834: newp = fStartNew + (p - fStart)*2 + r;
9835: DMLabelSetValue(labelNew, newp, values[val]);
9836: }
9837: } else if ((p >= fMax) && (p < fEnd)) {
9838: /* Old hybrid faces stay the same */
9839: newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
9840: DMLabelSetValue(labelNew, newp, values[val]);
9841: } else if ((p >= cStart) && (p < cMax)) {
9842: /* Old interior cells add new cells and interior faces */
9843: for (r = 0; r < 4; ++r) {
9844: newp = cStartNew + (p - cStart)*4 + r;
9845: DMLabelSetValue(labelNew, newp, values[val]);
9846: }
9847: for (r = 0; r < 3; ++r) {
9848: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
9849: DMLabelSetValue(labelNew, newp, values[val]);
9850: }
9851: } else if ((p >= cMax) && (p < cEnd)) {
9852: /* Old hybrid cells add new cells and hybrid face */
9853: for (r = 0; r < 2; ++r) {
9854: newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
9855: DMLabelSetValue(labelNew, newp, values[val]);
9856: }
9857: newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
9858: DMLabelSetValue(labelNew, newp, values[val]);
9859: }
9860: break;
9861: case REFINER_HYBRID_HEX_2D:
9862: if ((p >= vStart) && (p < vEnd)) {
9863: /* Old vertices stay the same */
9864: newp = vStartNew + (p - vStart);
9865: DMLabelSetValue(labelNew, newp, values[val]);
9866: } else if ((p >= fStart) && (p < fMax)) {
9867: /* Old interior faces add new faces and vertex */
9868: newp = vStartNew + (vEnd - vStart) + (p - fStart);
9869: DMLabelSetValue(labelNew, newp, values[val]);
9870: for (r = 0; r < 2; ++r) {
9871: newp = fStartNew + (p - fStart)*2 + r;
9872: DMLabelSetValue(labelNew, newp, values[val]);
9873: }
9874: } else if ((p >= fMax) && (p < fEnd)) {
9875: /* Old hybrid faces stay the same */
9876: newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
9877: DMLabelSetValue(labelNew, newp, values[val]);
9878: } else if ((p >= cStart) && (p < cMax)) {
9879: /* Old interior cells add new cells, interior faces, and vertex */
9880: for (r = 0; r < 4; ++r) {
9881: newp = cStartNew + (p - cStart)*4 + r;
9882: DMLabelSetValue(labelNew, newp, values[val]);
9883: }
9884: for (r = 0; r < 4; ++r) {
9885: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
9886: DMLabelSetValue(labelNew, newp, values[val]);
9887: }
9888: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
9889: DMLabelSetValue(labelNew, newp, values[val]);
9890: } else if ((p >= cMax) && (p < cEnd)) {
9891: /* Old hybrid cells add new cells and hybrid face */
9892: for (r = 0; r < 2; ++r) {
9893: newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
9894: DMLabelSetValue(labelNew, newp, values[val]);
9895: }
9896: newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
9897: DMLabelSetValue(labelNew, newp, values[val]);
9898: }
9899: break;
9900: case REFINER_SIMPLEX_3D:
9901: if ((p >= vStart) && (p < vEnd)) {
9902: /* Old vertices stay the same */
9903: newp = vStartNew + (p - vStart);
9904: DMLabelSetValue(labelNew, newp, values[val]);
9905: } else if ((p >= eStart) && (p < eEnd)) {
9906: /* Old edges add new edges and vertex */
9907: for (r = 0; r < 2; ++r) {
9908: newp = eStartNew + (p - eStart)*2 + r;
9909: DMLabelSetValue(labelNew, newp, values[val]);
9910: }
9911: newp = vStartNew + (vEnd - vStart) + (p - eStart);
9912: DMLabelSetValue(labelNew, newp, values[val]);
9913: } else if ((p >= fStart) && (p < fEnd)) {
9914: /* Old faces add new faces and edges */
9915: for (r = 0; r < 4; ++r) {
9916: newp = fStartNew + (p - fStart)*4 + r;
9917: DMLabelSetValue(labelNew, newp, values[val]);
9918: }
9919: for (r = 0; r < 3; ++r) {
9920: newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
9921: DMLabelSetValue(labelNew, newp, values[val]);
9922: }
9923: } else if ((p >= cStart) && (p < cEnd)) {
9924: /* Old cells add new cells and interior faces and edges */
9925: for (r = 0; r < 8; ++r) {
9926: newp = cStartNew + (p - cStart)*8 + r;
9927: DMLabelSetValue(labelNew, newp, values[val]);
9928: }
9929: for (r = 0; r < 8; ++r) {
9930: newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
9931: DMLabelSetValue(labelNew, newp, values[val]);
9932: }
9933: for (r = 0; r < 1; ++r) {
9934: newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
9935: DMLabelSetValue(labelNew, newp, values[val]);
9936: }
9937: }
9938: break;
9939: case REFINER_HYBRID_SIMPLEX_TO_HEX_3D:
9940: case REFINER_SIMPLEX_TO_HEX_3D:
9941: if ((p >= vStart) && (p < vEnd)) {
9942: /* Old vertices stay the same */
9943: newp = vStartNew + (p - vStart);
9944: DMLabelSetValue(labelNew, newp, values[val]);
9945: } else if ((p >= eStart) && (p < eMax)) {
9946: /* Interior edges add new edges and vertex */
9947: for (r = 0; r < 2; ++r) {
9948: newp = eStartNew + (p - eStart)*2 + r;
9949: DMLabelSetValue(labelNew, newp, values[val]);
9950: }
9951: newp = vStartNew + (vEnd - vStart) + (p - eStart);
9952: DMLabelSetValue(labelNew, newp, values[val]);
9953: } else if ((p >= eMax) && (p < eEnd)) {
9954: /* Hybrid edges stay the same */
9955: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + p - eMax;
9956: DMLabelSetValue(labelNew, newp, values[val]);
9957: } else if ((p >= fStart) && (p < fMax)) {
9958: /* Old faces add new faces, edges and a vertex */
9959: for (r = 0; r < 3; ++r) {
9960: newp = fStartNew + (p - fStart)*3 + r;
9961: DMLabelSetValue(labelNew, newp, values[val]);
9962: }
9963: for (r = 0; r < 3; ++r) {
9964: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
9965: DMLabelSetValue(labelNew, newp, values[val]);
9966: }
9967: } else if ((p >= fMax) && (p < fEnd)) {
9968: /* Old hybrid faces add new faces and an edge */
9969: for (r = 0; r < 2; ++r) {
9970: newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r;
9971: DMLabelSetValue(labelNew, newp, values[val]);
9972: }
9973: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax);
9974: DMLabelSetValue(labelNew, newp, values[val]);
9975: } else if ((p >= cStart) && (p < cMax)) {
9976: /* Old cells add new cells and interior faces and edges and a vertex */
9977: for (r = 0; r < 4; ++r) {
9978: newp = cStartNew + (p - cStart)*4 + r;
9979: DMLabelSetValue(labelNew, newp, values[val]);
9980: }
9981: for (r = 0; r < 6; ++r) {
9982: newp = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r;
9983: DMLabelSetValue(labelNew, newp, values[val]);
9984: }
9985: for (r = 0; r < 4; ++r) {
9986: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r;
9987: DMLabelSetValue(labelNew, newp, values[val]);
9988: }
9989: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + p - cStart;
9990: DMLabelSetValue(labelNew, newp, values[val]);
9991: } else if ((p >= cMax) && (p < cEnd)) {
9992: /* Old hybrid cells add new cells and interior faces and an edge */
9993: for (r = 0; r < 3; ++r) {
9994: newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r;
9995: DMLabelSetValue(labelNew, newp, values[val]);
9996: }
9997: for (r = 0; r < 3; ++r) {
9998: newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
9999: DMLabelSetValue(labelNew, newp, values[val]);
10000: }
10001: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + p - cMax;
10002: DMLabelSetValue(labelNew, newp, values[val]);
10003: }
10004: break;
10005: case REFINER_HYBRID_SIMPLEX_3D:
10006: if ((p >= vStart) && (p < vEnd)) {
10007: /* Interior vertices stay the same */
10008: newp = vStartNew + (p - vStart);
10009: DMLabelSetValue(labelNew, newp, values[val]);
10010: } else if ((p >= eStart) && (p < eMax)) {
10011: /* Interior edges add new edges and vertex */
10012: for (r = 0; r < 2; ++r) {
10013: newp = eStartNew + (p - eStart)*2 + r;
10014: DMLabelSetValue(labelNew, newp, values[val]);
10015: }
10016: newp = vStartNew + (vEnd - vStart) + (p - eStart);
10017: DMLabelSetValue(labelNew, newp, values[val]);
10018: } else if ((p >= eMax) && (p < eEnd)) {
10019: /* Hybrid edges stay the same */
10020: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
10021: DMLabelSetValue(labelNew, newp, values[val]);
10022: } else if ((p >= fStart) && (p < fMax)) {
10023: /* Interior faces add new faces and edges */
10024: for (r = 0; r < 4; ++r) {
10025: newp = fStartNew + (p - fStart)*4 + r;
10026: DMLabelSetValue(labelNew, newp, values[val]);
10027: }
10028: for (r = 0; r < 3; ++r) {
10029: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
10030: DMLabelSetValue(labelNew, newp, values[val]);
10031: }
10032: } else if ((p >= fMax) && (p < fEnd)) {
10033: /* Hybrid faces add new faces and edges */
10034: for (r = 0; r < 2; ++r) {
10035: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
10036: DMLabelSetValue(labelNew, newp, values[val]);
10037: }
10038: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
10039: DMLabelSetValue(labelNew, newp, values[val]);
10040: } else if ((p >= cStart) && (p < cMax)) {
10041: /* Interior cells add new cells, faces, and edges */
10042: for (r = 0; r < 8; ++r) {
10043: newp = cStartNew + (p - cStart)*8 + r;
10044: DMLabelSetValue(labelNew, newp, values[val]);
10045: }
10046: for (r = 0; r < 8; ++r) {
10047: newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
10048: DMLabelSetValue(labelNew, newp, values[val]);
10049: }
10050: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
10051: DMLabelSetValue(labelNew, newp, values[val]);
10052: } else if ((p >= cMax) && (p < cEnd)) {
10053: /* Hybrid cells add new cells and faces */
10054: for (r = 0; r < 4; ++r) {
10055: newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
10056: DMLabelSetValue(labelNew, newp, values[val]);
10057: }
10058: for (r = 0; r < 3; ++r) {
10059: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
10060: DMLabelSetValue(labelNew, newp, values[val]);
10061: }
10062: }
10063: break;
10064: case REFINER_HEX_3D:
10065: if ((p >= vStart) && (p < vEnd)) {
10066: /* Old vertices stay the same */
10067: newp = vStartNew + (p - vStart);
10068: DMLabelSetValue(labelNew, newp, values[val]);
10069: } else if ((p >= eStart) && (p < eEnd)) {
10070: /* Old edges add new edges and vertex */
10071: for (r = 0; r < 2; ++r) {
10072: newp = eStartNew + (p - eStart)*2 + r;
10073: DMLabelSetValue(labelNew, newp, values[val]);
10074: }
10075: newp = vStartNew + (vEnd - vStart) + (p - eStart);
10076: DMLabelSetValue(labelNew, newp, values[val]);
10077: } else if ((p >= fStart) && (p < fEnd)) {
10078: /* Old faces add new faces, edges, and vertex */
10079: for (r = 0; r < 4; ++r) {
10080: newp = fStartNew + (p - fStart)*4 + r;
10081: DMLabelSetValue(labelNew, newp, values[val]);
10082: }
10083: for (r = 0; r < 4; ++r) {
10084: newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
10085: DMLabelSetValue(labelNew, newp, values[val]);
10086: }
10087: newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
10088: DMLabelSetValue(labelNew, newp, values[val]);
10089: } else if ((p >= cStart) && (p < cEnd)) {
10090: /* Old cells add new cells, faces, edges, and vertex */
10091: for (r = 0; r < 8; ++r) {
10092: newp = cStartNew + (p - cStart)*8 + r;
10093: DMLabelSetValue(labelNew, newp, values[val]);
10094: }
10095: for (r = 0; r < 12; ++r) {
10096: newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
10097: DMLabelSetValue(labelNew, newp, values[val]);
10098: }
10099: for (r = 0; r < 6; ++r) {
10100: newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
10101: DMLabelSetValue(labelNew, newp, values[val]);
10102: }
10103: newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
10104: DMLabelSetValue(labelNew, newp, values[val]);
10105: }
10106: break;
10107: case REFINER_HYBRID_HEX_3D:
10108: if ((p >= vStart) && (p < vEnd)) {
10109: /* Interior vertices stay the same */
10110: newp = vStartNew + (p - vStart);
10111: DMLabelSetValue(labelNew, newp, values[val]);
10112: } else if ((p >= eStart) && (p < eMax)) {
10113: /* Interior edges add new edges and vertex */
10114: for (r = 0; r < 2; ++r) {
10115: newp = eStartNew + (p - eStart)*2 + r;
10116: DMLabelSetValue(labelNew, newp, values[val]);
10117: }
10118: newp = vStartNew + (vEnd - vStart) + (p - eStart);
10119: DMLabelSetValue(labelNew, newp, values[val]);
10120: } else if ((p >= eMax) && (p < eEnd)) {
10121: /* Hybrid edges stay the same */
10122: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
10123: DMLabelSetValue(labelNew, newp, values[val]);
10124: } else if ((p >= fStart) && (p < fMax)) {
10125: /* Interior faces add new faces, edges, and vertex */
10126: for (r = 0; r < 4; ++r) {
10127: newp = fStartNew + (p - fStart)*4 + r;
10128: DMLabelSetValue(labelNew, newp, values[val]);
10129: }
10130: for (r = 0; r < 4; ++r) {
10131: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
10132: DMLabelSetValue(labelNew, newp, values[val]);
10133: }
10134: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
10135: DMLabelSetValue(labelNew, newp, values[val]);
10136: } else if ((p >= fMax) && (p < fEnd)) {
10137: /* Hybrid faces add new faces and edges */
10138: for (r = 0; r < 2; ++r) {
10139: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
10140: DMLabelSetValue(labelNew, newp, values[val]);
10141: }
10142: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
10143: DMLabelSetValue(labelNew, newp, values[val]);
10144: } else if ((p >= cStart) && (p < cMax)) {
10145: /* Interior cells add new cells, faces, edges, and vertex */
10146: for (r = 0; r < 8; ++r) {
10147: newp = cStartNew + (p - cStart)*8 + r;
10148: DMLabelSetValue(labelNew, newp, values[val]);
10149: }
10150: for (r = 0; r < 12; ++r) {
10151: newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
10152: DMLabelSetValue(labelNew, newp, values[val]);
10153: }
10154: for (r = 0; r < 6; ++r) {
10155: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
10156: DMLabelSetValue(labelNew, newp, values[val]);
10157: }
10158: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
10159: DMLabelSetValue(labelNew, newp, values[val]);
10160: } else if ((p >= cMax) && (p < cEnd)) {
10161: /* Hybrid cells add new cells, faces, and edges */
10162: for (r = 0; r < 4; ++r) {
10163: newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
10164: DMLabelSetValue(labelNew, newp, values[val]);
10165: }
10166: for (r = 0; r < 4; ++r) {
10167: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
10168: DMLabelSetValue(labelNew, newp, values[val]);
10169: }
10170: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
10171: DMLabelSetValue(labelNew, newp, values[val]);
10172: }
10173: break;
10174: default:
10175: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]);
10176: }
10177: }
10178: ISRestoreIndices(pointIS, &points);
10179: ISDestroy(&pointIS);
10180: }
10181: ISRestoreIndices(valueIS, &values);
10182: ISDestroy(&valueIS);
10183: }
10184: return(0);
10185: }
10187: /* This will only work for interpolated meshes */
10188: PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
10189: {
10190: DM rdm;
10191: PetscInt *depthSize;
10192: PetscInt dim, embedDim, depth = 0, d, pStart = 0, pEnd = 0;
10196: DMCreate(PetscObjectComm((PetscObject)dm), &rdm);
10197: DMSetType(rdm, DMPLEX);
10198: DMGetDimension(dm, &dim);
10199: DMSetDimension(rdm, dim);
10200: DMGetCoordinateDim(dm, &embedDim);
10201: DMSetCoordinateDim(rdm, embedDim);
10202: /* Calculate number of new points of each depth */
10203: DMPlexGetDepth(dm, &depth);
10204: if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
10205: PetscMalloc1(depth+1, &depthSize);
10206: PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));
10207: CellRefinerGetSizes(cellRefiner, dm, depthSize);
10208: /* Step 1: Set chart */
10209: for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
10210: DMPlexSetChart(rdm, pStart, pEnd);
10211: /* Step 2: Set cone/support sizes (automatically stratifies) */
10212: CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);
10213: /* Step 3: Setup refined DM */
10214: DMSetUp(rdm);
10215: /* Step 4: Set cones and supports (automatically symmetrizes) */
10216: CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);
10217: /* Step 5: Create pointSF */
10218: CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);
10219: /* Step 6: Create labels */
10220: CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);
10221: /* Step 7: Set coordinates */
10222: CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);
10223: PetscFree(depthSize);
10225: *dmRefined = rdm;
10226: return(0);
10227: }
10229: /*@
10230: DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
10232: Input Parameter:
10233: . dm - The coarse DM
10235: Output Parameter:
10236: . fpointIS - The IS of all the fine points which exist in the original coarse mesh
10238: Level: developer
10240: .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
10241: @*/
10242: PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
10243: {
10244: CellRefiner cellRefiner;
10245: PetscInt *depthSize, *fpoints;
10246: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
10247: PetscInt depth, pStart, pEnd, p, vStart, vEnd, v;
10251: DMPlexGetDepth(dm, &depth);
10252: DMPlexGetChart(dm, &pStart, &pEnd);
10253: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
10254: DMPlexGetCellRefiner_Internal(dm, &cellRefiner);
10255: PetscMalloc1(depth+1, &depthSize);
10256: CellRefinerGetSizes(cellRefiner, dm, depthSize);
10257: if (cellRefiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
10258: PetscMalloc1(pEnd-pStart,&fpoints);
10259: for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
10260: switch (cellRefiner) {
10261: case REFINER_SIMPLEX_1D:
10262: case REFINER_SIMPLEX_2D:
10263: case REFINER_HYBRID_SIMPLEX_2D:
10264: case REFINER_HEX_2D:
10265: case REFINER_HYBRID_HEX_2D:
10266: case REFINER_SIMPLEX_3D:
10267: case REFINER_HYBRID_SIMPLEX_3D:
10268: case REFINER_HEX_3D:
10269: case REFINER_HYBRID_HEX_3D:
10270: for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
10271: break;
10272: default:
10273: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[cellRefiner]);
10274: }
10275: ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);
10276: PetscFree(depthSize);
10277: return(0);
10278: }
10280: /*@
10281: DMPlexSetRefinementUniform - Set the flag for uniform refinement
10283: Input Parameters:
10284: + dm - The DM
10285: - refinementUniform - The flag for uniform refinement
10287: Level: developer
10289: .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10290: @*/
10291: PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
10292: {
10293: DM_Plex *mesh = (DM_Plex*) dm->data;
10297: mesh->refinementUniform = refinementUniform;
10298: return(0);
10299: }
10301: /*@
10302: DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
10304: Input Parameter:
10305: . dm - The DM
10307: Output Parameter:
10308: . refinementUniform - The flag for uniform refinement
10310: Level: developer
10312: .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10313: @*/
10314: PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
10315: {
10316: DM_Plex *mesh = (DM_Plex*) dm->data;
10321: *refinementUniform = mesh->refinementUniform;
10322: return(0);
10323: }
10325: /*@
10326: DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
10328: Input Parameters:
10329: + dm - The DM
10330: - refinementLimit - The maximum cell volume in the refined mesh
10332: Level: developer
10334: .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
10335: @*/
10336: PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
10337: {
10338: DM_Plex *mesh = (DM_Plex*) dm->data;
10342: mesh->refinementLimit = refinementLimit;
10343: return(0);
10344: }
10346: /*@
10347: DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
10349: Input Parameter:
10350: . dm - The DM
10352: Output Parameter:
10353: . refinementLimit - The maximum cell volume in the refined mesh
10355: Level: developer
10357: .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
10358: @*/
10359: PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
10360: {
10361: DM_Plex *mesh = (DM_Plex*) dm->data;
10366: /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
10367: *refinementLimit = mesh->refinementLimit;
10368: return(0);
10369: }
10371: /*@
10372: DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
10374: Input Parameters:
10375: + dm - The DM
10376: - refinementFunc - Function giving the maximum cell volume in the refined mesh
10378: Note: The calling sequence is refinementFunc(coords, limit)
10379: $ coords - Coordinates of the current point, usually a cell centroid
10380: $ limit - The maximum cell volume for a cell containing this point
10382: Level: developer
10384: .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10385: @*/
10386: PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
10387: {
10388: DM_Plex *mesh = (DM_Plex*) dm->data;
10392: mesh->refinementFunc = refinementFunc;
10393: return(0);
10394: }
10396: /*@
10397: DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
10399: Input Parameter:
10400: . dm - The DM
10402: Output Parameter:
10403: . refinementFunc - Function giving the maximum cell volume in the refined mesh
10405: Note: The calling sequence is refinementFunc(coords, limit)
10406: $ coords - Coordinates of the current point, usually a cell centroid
10407: $ limit - The maximum cell volume for a cell containing this point
10409: Level: developer
10411: .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
10412: @*/
10413: PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
10414: {
10415: DM_Plex *mesh = (DM_Plex*) dm->data;
10420: *refinementFunc = mesh->refinementFunc;
10421: return(0);
10422: }
10424: PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
10425: {
10426: PetscInt dim, cStart, cEnd, coneSize, cMax, fMax;
10430: DMGetDimension(dm, &dim);
10431: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
10432: if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; return(0);}
10433: DMPlexGetConeSize(dm, cStart, &coneSize);
10434: DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);
10435: switch (dim) {
10436: case 1:
10437: switch (coneSize) {
10438: case 2:
10439: *cellRefiner = REFINER_SIMPLEX_1D;
10440: break;
10441: default:
10442: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10443: }
10444: break;
10445: case 2:
10446: switch (coneSize) {
10447: case 3:
10448: if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D;
10449: else *cellRefiner = REFINER_SIMPLEX_2D;
10450: break;
10451: case 4:
10452: if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D;
10453: else *cellRefiner = REFINER_HEX_2D;
10454: break;
10455: default:
10456: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10457: }
10458: break;
10459: case 3:
10460: switch (coneSize) {
10461: case 4:
10462: if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
10463: else *cellRefiner = REFINER_SIMPLEX_3D;
10464: break;
10465: case 5:
10466: if (cMax == 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
10467: else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10468: break;
10469: case 6:
10470: if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D;
10471: else *cellRefiner = REFINER_HEX_3D;
10472: break;
10473: default:
10474: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim);
10475: }
10476: break;
10477: default:
10478: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %D for cell refiner", dim);
10479: }
10480: return(0);
10481: }
10483: PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined)
10484: {
10485: PetscBool isUniform;
10489: DMPlexGetRefinementUniform(dm, &isUniform);
10490: if (isUniform) {
10491: CellRefiner cellRefiner;
10492: PetscBool localized;
10494: DMGetCoordinatesLocalized(dm, &localized);
10495: DMPlexGetCellRefiner_Internal(dm, &cellRefiner);
10496: DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);
10497: DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);
10498: DMCopyBoundary(dm, *dmRefined);
10499: if (localized) {DMLocalizeCoordinates(*dmRefined);}
10500: } else {
10501: DMPlexRefine_Internal(dm, NULL, dmRefined);
10502: }
10503: return(0);
10504: }
10506: PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[])
10507: {
10508: DM cdm = dm;
10509: PetscInt r;
10510: PetscBool isUniform, localized;
10514: DMPlexGetRefinementUniform(dm, &isUniform);
10515: DMGetCoordinatesLocalized(dm, &localized);
10516: if (isUniform) {
10517: for (r = 0; r < nlevels; ++r) {
10518: CellRefiner cellRefiner;
10520: DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);
10521: DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);
10522: DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);
10523: DMSetRefineLevel(dmRefined[r], cdm->levelup+1);
10524: DMCopyBoundary(cdm, dmRefined[r]);
10525: if (localized) {DMLocalizeCoordinates(dmRefined[r]);}
10526: DMSetCoarseDM(dmRefined[r], cdm);
10527: DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);
10528: cdm = dmRefined[r];
10529: }
10530: } else {
10531: for (r = 0; r < nlevels; ++r) {
10532: DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);
10533: DMCopyBoundary(cdm, dmRefined[r]);
10534: if (localized) {DMLocalizeCoordinates(dmRefined[r]);}
10535: DMSetCoarseDM(dmRefined[r], cdm);
10536: cdm = dmRefined[r];
10537: }
10538: }
10539: return(0);
10540: }