Actual source code: plexrefine.c
petsc-dev 2014-02-02
1: #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/
2: #include <petscsf.h>
6: PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart)
7: {
9: if (cStart) *cStart = 0;
10: if (vStart) *vStart = depthSize[depth];
11: if (fStart) *fStart = depthSize[depth] + depthSize[0];
12: if (eStart) *eStart = depthSize[depth] + depthSize[0] + depthSize[depth-1];
13: return(0);
14: }
18: PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd)
19: {
21: if (cEnd) *cEnd = depthSize[depth];
22: if (vEnd) *vEnd = depthSize[depth] + depthSize[0];
23: if (fEnd) *fEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1];
24: if (eEnd) *eEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1];
25: return(0);
26: }
30: static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
31: {
32: PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
36: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
37: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
38: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
39: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
40: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
41: switch (refiner) {
42: case 0:
43: break;
44: case 1:
45: /* Simplicial 2D */
46: depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */
47: depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */
48: depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
49: break;
50: case 3:
51: /* Hybrid Simplicial 2D */
52: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
53: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
54: depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */
55: 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 */
56: depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
57: break;
58: case 2:
59: /* Hex 2D */
60: depthSize[0] = vEnd - vStart + cEnd - cStart + fEnd - fStart; /* Add a vertex on every face and cell */
61: depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */
62: depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */
63: break;
64: case 5:
65: /* Simplicial 3D */
66: depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */
67: 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 */
68: depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */
69: depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */
70: break;
71: case 7:
72: /* Hybrid Simplicial 3D */
73: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
74: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
75: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
76: /* Tetrahedra */
77: depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */
78: 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 */
79: depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */
80: depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */
81: /* Triangular Prisms */
82: depthSize[0] += 0; /* No hybrid vertices */
83: depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */
84: depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */
85: depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */
86: break;
87: case 6:
88: /* Hex 3D */
89: depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
90: 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 */
91: depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */
92: depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */
93: break;
94: case 8:
95: /* Hybrid Hex 3D */
96: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
97: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
98: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
99: /* Hexahedra */
100: depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
101: 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 */
102: depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */
103: depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */
104: /* Quadrilateral Prisms */
105: depthSize[0] += 0; /* No hybrid vertices */
106: depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
107: depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */
108: depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */
109: break;
110: default:
111: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
112: }
113: return(0);
114: }
116: /* Return triangle edge for orientation o, if it is r for o == 0 */
117: PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
118: return (o < 0 ? 2-(o+r) : o+r)%3;
119: }
120: PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
121: return (o < 0 ? 2-(o+s) : 3+s-o)%3;
122: }
124: /* Return triangle subface for orientation o, if it is r for o == 0 */
125: PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
126: return (o < 0 ? 3-(o+r) : o+r)%3;
127: }
128: PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
129: return (o < 0 ? 3-(o+s) : 3+s-o)%3;
130: }
132: /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
133: PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
134: return (o < 0 ? 1-(o+r) : o+r)%3;
135: }
136: PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
137: return (o < 0 ? 1-(o+s) : 3+s-o)%3;
138: }
141: /* Return quad edge for orientation o, if it is r for o == 0 */
142: PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
143: return (o < 0 ? 3-(o+r) : o+r)%4;
144: }
145: PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
146: return (o < 0 ? 3-(o+s) : 4+s-o)%4;
147: }
149: /* Return quad subface for orientation o, if it is r for o == 0 */
150: PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
151: return (o < 0 ? 4-(o+r) : o+r)%4;
152: }
153: PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
154: return (o < 0 ? 4-(o+s) : 4+s-o)%4;
155: }
159: static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
160: {
161: PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r;
165: DMPlexGetDepth(dm, &depth);
166: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
167: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
168: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
169: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
170: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
171: if (refiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
172: switch (refiner) {
173: case 0: break;
174: case 1:
175: /* Simplicial 2D */
176: /* All cells have 3 faces */
177: for (c = cStart; c < cEnd; ++c) {
178: for (r = 0; r < 4; ++r) {
179: const PetscInt newp = (c - cStart)*4 + r;
181: DMPlexSetConeSize(rdm, newp, 3);
182: }
183: }
184: /* Split faces have 2 vertices and the same cells as the parent */
185: for (f = fStart; f < fEnd; ++f) {
186: for (r = 0; r < 2; ++r) {
187: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
188: PetscInt size;
190: DMPlexSetConeSize(rdm, newp, 2);
191: DMPlexGetSupportSize(dm, f, &size);
192: DMPlexSetSupportSize(rdm, newp, size);
193: }
194: }
195: /* Interior faces have 2 vertices and 2 cells */
196: for (c = cStart; c < cEnd; ++c) {
197: for (r = 0; r < 3; ++r) {
198: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
200: DMPlexSetConeSize(rdm, newp, 2);
201: DMPlexSetSupportSize(rdm, newp, 2);
202: }
203: }
204: /* Old vertices have identical supports */
205: for (v = vStart; v < vEnd; ++v) {
206: const PetscInt newp = vStartNew + (v - vStart);
207: PetscInt size;
209: DMPlexGetSupportSize(dm, v, &size);
210: DMPlexSetSupportSize(rdm, newp, size);
211: }
212: /* Face vertices have 2 + cells*2 supports */
213: for (f = fStart; f < fEnd; ++f) {
214: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
215: PetscInt size;
217: DMPlexGetSupportSize(dm, f, &size);
218: DMPlexSetSupportSize(rdm, newp, 2 + size*2);
219: }
220: break;
221: case 2:
222: /* Hex 2D */
223: /* All cells have 4 faces */
224: for (c = cStart; c < cEnd; ++c) {
225: for (r = 0; r < 4; ++r) {
226: const PetscInt newp = (c - cStart)*4 + r;
228: DMPlexSetConeSize(rdm, newp, 4);
229: }
230: }
231: /* Split faces have 2 vertices and the same cells as the parent */
232: for (f = fStart; f < fEnd; ++f) {
233: for (r = 0; r < 2; ++r) {
234: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
235: PetscInt size;
237: DMPlexSetConeSize(rdm, newp, 2);
238: DMPlexGetSupportSize(dm, f, &size);
239: DMPlexSetSupportSize(rdm, newp, size);
240: }
241: }
242: /* Interior faces have 2 vertices and 2 cells */
243: for (c = cStart; c < cEnd; ++c) {
244: for (r = 0; r < 4; ++r) {
245: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
247: DMPlexSetConeSize(rdm, newp, 2);
248: DMPlexSetSupportSize(rdm, newp, 2);
249: }
250: }
251: /* Old vertices have identical supports */
252: for (v = vStart; v < vEnd; ++v) {
253: const PetscInt newp = vStartNew + (v - vStart);
254: PetscInt size;
256: DMPlexGetSupportSize(dm, v, &size);
257: DMPlexSetSupportSize(rdm, newp, size);
258: }
259: /* Face vertices have 2 + cells supports */
260: for (f = fStart; f < fEnd; ++f) {
261: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
262: PetscInt size;
264: DMPlexGetSupportSize(dm, f, &size);
265: DMPlexSetSupportSize(rdm, newp, 2 + size);
266: }
267: /* Cell vertices have 4 supports */
268: for (c = cStart; c < cEnd; ++c) {
269: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
271: DMPlexSetSupportSize(rdm, newp, 4);
272: }
273: break;
274: case 3:
275: /* Hybrid Simplicial 2D */
276: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
277: cMax = PetscMin(cEnd, cMax);
278: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
279: fMax = PetscMin(fEnd, fMax);
280: DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);
281: /* Interior cells have 3 faces */
282: for (c = cStart; c < cMax; ++c) {
283: for (r = 0; r < 4; ++r) {
284: const PetscInt newp = cStartNew + (c - cStart)*4 + r;
286: DMPlexSetConeSize(rdm, newp, 3);
287: }
288: }
289: /* Hybrid cells have 4 faces */
290: for (c = cMax; c < cEnd; ++c) {
291: for (r = 0; r < 2; ++r) {
292: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
294: DMPlexSetConeSize(rdm, newp, 4);
295: }
296: }
297: /* Interior split faces have 2 vertices and the same cells as the parent */
298: for (f = fStart; f < fMax; ++f) {
299: for (r = 0; r < 2; ++r) {
300: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
301: PetscInt size;
303: DMPlexSetConeSize(rdm, newp, 2);
304: DMPlexGetSupportSize(dm, f, &size);
305: DMPlexSetSupportSize(rdm, newp, size);
306: }
307: }
308: /* Interior cell faces have 2 vertices and 2 cells */
309: for (c = cStart; c < cMax; ++c) {
310: for (r = 0; r < 3; ++r) {
311: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
313: DMPlexSetConeSize(rdm, newp, 2);
314: DMPlexSetSupportSize(rdm, newp, 2);
315: }
316: }
317: /* Hybrid faces have 2 vertices and the same cells */
318: for (f = fMax; f < fEnd; ++f) {
319: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
320: PetscInt size;
322: DMPlexSetConeSize(rdm, newp, 2);
323: DMPlexGetSupportSize(dm, f, &size);
324: DMPlexSetSupportSize(rdm, newp, size);
325: }
326: /* Hybrid cell faces have 2 vertices and 2 cells */
327: for (c = cMax; c < cEnd; ++c) {
328: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
330: DMPlexSetConeSize(rdm, newp, 2);
331: DMPlexSetSupportSize(rdm, newp, 2);
332: }
333: /* Old vertices have identical supports */
334: for (v = vStart; v < vEnd; ++v) {
335: const PetscInt newp = vStartNew + (v - vStart);
336: PetscInt size;
338: DMPlexGetSupportSize(dm, v, &size);
339: DMPlexSetSupportSize(rdm, newp, size);
340: }
341: /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
342: for (f = fStart; f < fMax; ++f) {
343: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
344: const PetscInt *support;
345: PetscInt size, newSize = 2, s;
347: DMPlexGetSupportSize(dm, f, &size);
348: DMPlexGetSupport(dm, f, &support);
349: for (s = 0; s < size; ++s) {
350: if (support[s] >= cMax) newSize += 1;
351: else newSize += 2;
352: }
353: DMPlexSetSupportSize(rdm, newp, newSize);
354: }
355: break;
356: case 5:
357: /* Simplicial 3D */
358: /* All cells have 4 faces */
359: for (c = cStart; c < cEnd; ++c) {
360: for (r = 0; r < 8; ++r) {
361: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
363: DMPlexSetConeSize(rdm, newp, 4);
364: }
365: }
366: /* Split faces have 3 edges and the same cells as the parent */
367: for (f = fStart; f < fEnd; ++f) {
368: for (r = 0; r < 4; ++r) {
369: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
370: PetscInt size;
372: DMPlexSetConeSize(rdm, newp, 3);
373: DMPlexGetSupportSize(dm, f, &size);
374: DMPlexSetSupportSize(rdm, newp, size);
375: }
376: }
377: /* Interior cell faces have 3 edges and 2 cells */
378: for (c = cStart; c < cEnd; ++c) {
379: for (r = 0; r < 8; ++r) {
380: const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
382: DMPlexSetConeSize(rdm, newp, 3);
383: DMPlexSetSupportSize(rdm, newp, 2);
384: }
385: }
386: /* Split edges have 2 vertices and the same faces */
387: for (e = eStart; e < eEnd; ++e) {
388: for (r = 0; r < 2; ++r) {
389: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
390: PetscInt size;
392: DMPlexSetConeSize(rdm, newp, 2);
393: DMPlexGetSupportSize(dm, e, &size);
394: DMPlexSetSupportSize(rdm, newp, size);
395: }
396: }
397: /* Face edges have 2 vertices and 2+cells*(1/2) faces */
398: for (f = fStart; f < fEnd; ++f) {
399: for (r = 0; r < 3; ++r) {
400: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
401: const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
402: PetscInt coneSize, c, supportSize, s, er, intFaces = 0;
404: DMPlexSetConeSize(rdm, newp, 2);
405: DMPlexGetSupportSize(dm, f, &supportSize);
406: DMPlexGetSupport(dm, f, &support);
407: for (s = 0; s < supportSize; ++s) {
408: DMPlexGetConeSize(dm, support[s], &coneSize);
409: DMPlexGetCone(dm, support[s], &cone);
410: DMPlexGetConeOrientation(dm, support[s], &ornt);
411: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
412: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
413: er = GetTetSomethingInverse_Static(ornt[c], r);
414: if (er == eint[c]) {
415: intFaces += 1;
416: } else {
417: intFaces += 2;
418: }
419: }
420: DMPlexSetSupportSize(rdm, newp, 2+intFaces);
421: }
422: }
423: /* Interior cell edges have 2 vertices and 4 faces */
424: for (c = cStart; c < cEnd; ++c) {
425: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
427: DMPlexSetConeSize(rdm, newp, 2);
428: DMPlexSetSupportSize(rdm, newp, 4);
429: }
430: /* Old vertices have identical supports */
431: for (v = vStart; v < vEnd; ++v) {
432: const PetscInt newp = vStartNew + (v - vStart);
433: PetscInt size;
435: DMPlexGetSupportSize(dm, v, &size);
436: DMPlexSetSupportSize(rdm, newp, size);
437: }
438: /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
439: for (e = eStart; e < eEnd; ++e) {
440: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
441: PetscInt size, *star = NULL, starSize, s, cellSize = 0;
443: DMPlexGetSupportSize(dm, e, &size);
444: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
445: for (s = 0; s < starSize*2; s += 2) {
446: const PetscInt *cone, *ornt;
447: PetscInt e01, e23;
449: if ((star[s] >= cStart) && (star[s] < cEnd)) {
450: /* Check edge 0-1 */
451: DMPlexGetCone(dm, star[s], &cone);
452: DMPlexGetConeOrientation(dm, star[s], &ornt);
453: DMPlexGetCone(dm, cone[0], &cone);
454: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
455: /* Check edge 2-3 */
456: DMPlexGetCone(dm, star[s], &cone);
457: DMPlexGetConeOrientation(dm, star[s], &ornt);
458: DMPlexGetCone(dm, cone[2], &cone);
459: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
460: if ((e01 == e) || (e23 == e)) ++cellSize;
461: }
462: }
463: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
464: DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);
465: }
466: break;
467: case 7:
468: /* Hybrid Simplicial 3D */
469: DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
470: eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);
471: /* Interior cells have 4 faces */
472: for (c = cStart; c < cMax; ++c) {
473: for (r = 0; r < 8; ++r) {
474: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
476: DMPlexSetConeSize(rdm, newp, 4);
477: }
478: }
479: /* Hybrid cells have 5 faces */
480: for (c = cMax; c < cEnd; ++c) {
481: for (r = 0; r < 4; ++r) {
482: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
484: DMPlexSetConeSize(rdm, newp, 5);
485: }
486: }
487: /* Interior split faces have 3 edges and the same cells as the parent */
488: for (f = fStart; f < fMax; ++f) {
489: for (r = 0; r < 4; ++r) {
490: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
491: PetscInt size;
493: DMPlexSetConeSize(rdm, newp, 3);
494: DMPlexGetSupportSize(dm, f, &size);
495: DMPlexSetSupportSize(rdm, newp, size);
496: }
497: }
498: /* Interior cell faces have 3 edges and 2 cells */
499: for (c = cStart; c < cMax; ++c) {
500: for (r = 0; r < 8; ++r) {
501: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
503: DMPlexSetConeSize(rdm, newp, 3);
504: DMPlexSetSupportSize(rdm, newp, 2);
505: }
506: }
507: /* Hybrid split faces have 4 edges and the same cells as the parent */
508: for (f = fMax; f < fEnd; ++f) {
509: for (r = 0; r < 2; ++r) {
510: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
511: PetscInt size;
513: DMPlexSetConeSize(rdm, newp, 4);
514: DMPlexGetSupportSize(dm, f, &size);
515: DMPlexSetSupportSize(rdm, newp, size);
516: }
517: }
518: /* Hybrid cells faces have 4 edges and 2 cells */
519: for (c = cMax; c < cEnd; ++c) {
520: for (r = 0; r < 3; ++r) {
521: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
523: DMPlexSetConeSize(rdm, newp, 4);
524: DMPlexSetSupportSize(rdm, newp, 2);
525: }
526: }
527: /* Interior split edges have 2 vertices and the same faces */
528: for (e = eStart; e < eMax; ++e) {
529: for (r = 0; r < 2; ++r) {
530: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
531: PetscInt size;
533: DMPlexSetConeSize(rdm, newp, 2);
534: DMPlexGetSupportSize(dm, e, &size);
535: DMPlexSetSupportSize(rdm, newp, size);
536: }
537: }
538: /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
539: for (f = fStart; f < fMax; ++f) {
540: for (r = 0; r < 3; ++r) {
541: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
542: const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
543: PetscInt coneSize, c, supportSize, s, er, intFaces = 0;
545: DMPlexSetConeSize(rdm, newp, 2);
546: DMPlexGetSupportSize(dm, f, &supportSize);
547: DMPlexGetSupport(dm, f, &support);
548: for (s = 0; s < supportSize; ++s) {
549: DMPlexGetConeSize(dm, support[s], &coneSize);
550: DMPlexGetCone(dm, support[s], &cone);
551: DMPlexGetConeOrientation(dm, support[s], &ornt);
552: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
553: if (support[s] < cMax) {
554: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
555: er = GetTetSomethingInverse_Static(ornt[c], r);
556: if (er == eint[c]) {
557: intFaces += 1;
558: } else {
559: intFaces += 2;
560: }
561: } else {
562: intFaces += 1;
563: }
564: }
565: DMPlexSetSupportSize(rdm, newp, 2+intFaces);
566: }
567: }
568: /* Interior cell edges have 2 vertices and 4 faces */
569: for (c = cStart; c < cMax; ++c) {
570: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
572: DMPlexSetConeSize(rdm, newp, 2);
573: DMPlexSetSupportSize(rdm, newp, 4);
574: }
575: /* Hybrid edges have 2 vertices and the same faces */
576: for (e = eMax; e < eEnd; ++e) {
577: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
578: PetscInt size;
580: DMPlexSetConeSize(rdm, newp, 2);
581: DMPlexGetSupportSize(dm, e, &size);
582: DMPlexSetSupportSize(rdm, newp, size);
583: }
584: /* Hybrid face edges have 2 vertices and 2+2*cells faces */
585: for (f = fMax; f < fEnd; ++f) {
586: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
587: PetscInt size;
589: DMPlexSetConeSize(rdm, newp, 2);
590: DMPlexGetSupportSize(dm, f, &size);
591: DMPlexSetSupportSize(rdm, newp, 2+2*size);
592: }
593: /* Interior vertices have identical supports */
594: for (v = vStart; v < vEnd; ++v) {
595: const PetscInt newp = vStartNew + (v - vStart);
596: PetscInt size;
598: DMPlexGetSupportSize(dm, v, &size);
599: DMPlexSetSupportSize(rdm, newp, size);
600: }
601: /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
602: for (e = eStart; e < eMax; ++e) {
603: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
604: const PetscInt *support;
605: PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
607: DMPlexGetSupportSize(dm, e, &size);
608: DMPlexGetSupport(dm, e, &support);
609: for (s = 0; s < size; ++s) {
610: if (support[s] < fMax) faceSize += 2;
611: else faceSize += 1;
612: }
613: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
614: for (s = 0; s < starSize*2; s += 2) {
615: const PetscInt *cone, *ornt;
616: PetscInt e01, e23;
618: if ((star[s] >= cStart) && (star[s] < cMax)) {
619: /* Check edge 0-1 */
620: DMPlexGetCone(dm, star[s], &cone);
621: DMPlexGetConeOrientation(dm, star[s], &ornt);
622: DMPlexGetCone(dm, cone[0], &cone);
623: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
624: /* Check edge 2-3 */
625: DMPlexGetCone(dm, star[s], &cone);
626: DMPlexGetConeOrientation(dm, star[s], &ornt);
627: DMPlexGetCone(dm, cone[2], &cone);
628: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
629: if ((e01 == e) || (e23 == e)) ++cellSize;
630: }
631: }
632: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
633: DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);
634: }
635: break;
636: case 6:
637: /* Hex 3D */
638: /* All cells have 6 faces */
639: for (c = cStart; c < cEnd; ++c) {
640: for (r = 0; r < 8; ++r) {
641: const PetscInt newp = (c - cStart)*8 + r;
643: DMPlexSetConeSize(rdm, newp, 6);
644: }
645: }
646: /* Split faces have 4 edges and the same cells as the parent */
647: for (f = fStart; f < fEnd; ++f) {
648: for (r = 0; r < 4; ++r) {
649: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
650: PetscInt size;
652: DMPlexSetConeSize(rdm, newp, 4);
653: DMPlexGetSupportSize(dm, f, &size);
654: DMPlexSetSupportSize(rdm, newp, size);
655: }
656: }
657: /* Interior faces have 4 edges and 2 cells */
658: for (c = cStart; c < cEnd; ++c) {
659: for (r = 0; r < 12; ++r) {
660: const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
662: DMPlexSetConeSize(rdm, newp, 4);
663: DMPlexSetSupportSize(rdm, newp, 2);
664: }
665: }
666: /* Split edges have 2 vertices and the same faces as the parent */
667: for (e = eStart; e < eEnd; ++e) {
668: for (r = 0; r < 2; ++r) {
669: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
670: PetscInt size;
672: DMPlexSetConeSize(rdm, newp, 2);
673: DMPlexGetSupportSize(dm, e, &size);
674: DMPlexSetSupportSize(rdm, newp, size);
675: }
676: }
677: /* Face edges have 2 vertices and 2+cells faces */
678: for (f = fStart; f < fEnd; ++f) {
679: for (r = 0; r < 4; ++r) {
680: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
681: PetscInt size;
683: DMPlexSetConeSize(rdm, newp, 2);
684: DMPlexGetSupportSize(dm, f, &size);
685: DMPlexSetSupportSize(rdm, newp, 2+size);
686: }
687: }
688: /* Cell edges have 2 vertices and 4 faces */
689: for (c = cStart; c < cEnd; ++c) {
690: for (r = 0; r < 6; ++r) {
691: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
693: DMPlexSetConeSize(rdm, newp, 2);
694: DMPlexSetSupportSize(rdm, newp, 4);
695: }
696: }
697: /* Old vertices have identical supports */
698: for (v = vStart; v < vEnd; ++v) {
699: const PetscInt newp = vStartNew + (v - vStart);
700: PetscInt size;
702: DMPlexGetSupportSize(dm, v, &size);
703: DMPlexSetSupportSize(rdm, newp, size);
704: }
705: /* Edge vertices have 2 + faces supports */
706: for (e = eStart; e < eEnd; ++e) {
707: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
708: PetscInt size;
710: DMPlexGetSupportSize(dm, e, &size);
711: DMPlexSetSupportSize(rdm, newp, 2 + size);
712: }
713: /* Face vertices have 4 + cells supports */
714: for (f = fStart; f < fEnd; ++f) {
715: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
716: PetscInt size;
718: DMPlexGetSupportSize(dm, f, &size);
719: DMPlexSetSupportSize(rdm, newp, 4 + size);
720: }
721: /* Cell vertices have 6 supports */
722: for (c = cStart; c < cEnd; ++c) {
723: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
725: DMPlexSetSupportSize(rdm, newp, 6);
726: }
727: break;
728: case 8:
729: /* Hybrid Hex 3D */
730: DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
731: eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);
732: /* Interior cells have 6 faces */
733: for (c = cStart; c < cMax; ++c) {
734: for (r = 0; r < 8; ++r) {
735: const PetscInt newp = cStartNew + (c - cStart)*8 + r;
737: DMPlexSetConeSize(rdm, newp, 6);
738: }
739: }
740: /* Hybrid cells have 6 faces */
741: for (c = cMax; c < cEnd; ++c) {
742: for (r = 0; r < 4; ++r) {
743: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
745: DMPlexSetConeSize(rdm, newp, 6);
746: }
747: }
748: /* Interior split faces have 4 edges and the same cells as the parent */
749: for (f = fStart; f < fMax; ++f) {
750: for (r = 0; r < 4; ++r) {
751: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
752: PetscInt size;
754: DMPlexSetConeSize(rdm, newp, 4);
755: DMPlexGetSupportSize(dm, f, &size);
756: DMPlexSetSupportSize(rdm, newp, size);
757: }
758: }
759: /* Interior cell faces have 4 edges and 2 cells */
760: for (c = cStart; c < cMax; ++c) {
761: for (r = 0; r < 12; ++r) {
762: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
764: DMPlexSetConeSize(rdm, newp, 4);
765: DMPlexSetSupportSize(rdm, newp, 2);
766: }
767: }
768: /* Hybrid split faces have 4 edges and the same cells as the parent */
769: for (f = fMax; f < fEnd; ++f) {
770: for (r = 0; r < 2; ++r) {
771: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
772: PetscInt size;
774: DMPlexSetConeSize(rdm, newp, 4);
775: DMPlexGetSupportSize(dm, f, &size);
776: DMPlexSetSupportSize(rdm, newp, size);
777: }
778: }
779: /* Hybrid cells faces have 4 edges and 2 cells */
780: for (c = cMax; c < cEnd; ++c) {
781: for (r = 0; r < 4; ++r) {
782: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
784: DMPlexSetConeSize(rdm, newp, 4);
785: DMPlexSetSupportSize(rdm, newp, 2);
786: }
787: }
788: /* Interior split edges have 2 vertices and the same faces as the parent */
789: for (e = eStart; e < eMax; ++e) {
790: for (r = 0; r < 2; ++r) {
791: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
792: PetscInt size;
794: DMPlexSetConeSize(rdm, newp, 2);
795: DMPlexGetSupportSize(dm, e, &size);
796: DMPlexSetSupportSize(rdm, newp, size);
797: }
798: }
799: /* Interior face edges have 2 vertices and 2+cells faces */
800: for (f = fStart; f < fMax; ++f) {
801: for (r = 0; r < 4; ++r) {
802: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
803: PetscInt size;
805: DMPlexSetConeSize(rdm, newp, 2);
806: DMPlexGetSupportSize(dm, f, &size);
807: DMPlexSetSupportSize(rdm, newp, 2+size);
808: }
809: }
810: /* Interior cell edges have 2 vertices and 4 faces */
811: for (c = cStart; c < cMax; ++c) {
812: for (r = 0; r < 6; ++r) {
813: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
815: DMPlexSetConeSize(rdm, newp, 2);
816: DMPlexSetSupportSize(rdm, newp, 4);
817: }
818: }
819: /* Hybrid edges have 2 vertices and the same faces */
820: for (e = eMax; e < eEnd; ++e) {
821: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
822: PetscInt size;
824: DMPlexSetConeSize(rdm, newp, 2);
825: DMPlexGetSupportSize(dm, e, &size);
826: DMPlexSetSupportSize(rdm, newp, size);
827: }
828: /* Hybrid face edges have 2 vertices and 2+cells faces */
829: for (f = fMax; f < fEnd; ++f) {
830: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
831: PetscInt size;
833: DMPlexSetConeSize(rdm, newp, 2);
834: DMPlexGetSupportSize(dm, f, &size);
835: DMPlexSetSupportSize(rdm, newp, 2+size);
836: }
837: /* Hybrid cell edges have 2 vertices and 4 faces */
838: for (c = cMax; c < cEnd; ++c) {
839: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
841: DMPlexSetConeSize(rdm, newp, 2);
842: DMPlexSetSupportSize(rdm, newp, 4);
843: }
844: /* Interior vertices have identical supports */
845: for (v = vStart; v < vEnd; ++v) {
846: const PetscInt newp = vStartNew + (v - vStart);
847: PetscInt size;
849: DMPlexGetSupportSize(dm, v, &size);
850: DMPlexSetSupportSize(rdm, newp, size);
851: }
852: /* Interior edge vertices have 2 + faces supports */
853: for (e = eStart; e < eMax; ++e) {
854: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
855: PetscInt size;
857: DMPlexGetSupportSize(dm, e, &size);
858: DMPlexSetSupportSize(rdm, newp, 2 + size);
859: }
860: /* Interior face vertices have 4 + cells supports */
861: for (f = fStart; f < fMax; ++f) {
862: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
863: PetscInt size;
865: DMPlexGetSupportSize(dm, f, &size);
866: DMPlexSetSupportSize(rdm, newp, 4 + size);
867: }
868: /* Interior cell vertices have 6 supports */
869: for (c = cStart; c < cMax; ++c) {
870: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
872: DMPlexSetSupportSize(rdm, newp, 6);
873: }
874: break;
875: default:
876: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
877: }
878: return(0);
879: }
883: static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
884: {
885: const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
886: PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
887: PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
888: PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
889: PetscErrorCode ierr;
892: DMPlexGetDepth(dm, &depth);
893: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
894: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
895: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
896: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
897: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
898: if (refiner) {
899: GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);
900: GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);
901: }
902: switch (refiner) {
903: case 0: break;
904: case 1:
905: /* Simplicial 2D */
906: /*
907: 2
908: |\
909: | \
910: | \
911: | \
912: | C \
913: | \
914: | \
915: 2---1---1
916: |\ D / \
917: | 2 0 \
918: |A \ / B \
919: 0---0-------1
920: */
921: /* All cells have 3 faces */
922: for (c = cStart; c < cEnd; ++c) {
923: const PetscInt newp = cStartNew + (c - cStart)*4;
924: const PetscInt *cone, *ornt;
925: PetscInt coneNew[3], orntNew[3];
927: DMPlexGetCone(dm, c, &cone);
928: DMPlexGetConeOrientation(dm, c, &ornt);
929: /* A triangle */
930: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
931: orntNew[0] = ornt[0];
932: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
933: orntNew[1] = -2;
934: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
935: orntNew[2] = ornt[2];
936: DMPlexSetCone(rdm, newp+0, coneNew);
937: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
938: #if 1
939: if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
940: for (p = 0; p < 3; ++p) {
941: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
942: }
943: #endif
944: /* B triangle */
945: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
946: orntNew[0] = ornt[0];
947: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
948: orntNew[1] = ornt[1];
949: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
950: orntNew[2] = -2;
951: DMPlexSetCone(rdm, newp+1, coneNew);
952: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
953: #if 1
954: if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
955: for (p = 0; p < 3; ++p) {
956: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
957: }
958: #endif
959: /* C triangle */
960: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
961: orntNew[0] = -2;
962: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
963: orntNew[1] = ornt[1];
964: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
965: orntNew[2] = ornt[2];
966: DMPlexSetCone(rdm, newp+2, coneNew);
967: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
968: #if 1
969: if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
970: for (p = 0; p < 3; ++p) {
971: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
972: }
973: #endif
974: /* D triangle */
975: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
976: orntNew[0] = 0;
977: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
978: orntNew[1] = 0;
979: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
980: orntNew[2] = 0;
981: DMPlexSetCone(rdm, newp+3, coneNew);
982: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
983: #if 1
984: if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
985: for (p = 0; p < 3; ++p) {
986: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
987: }
988: #endif
989: }
990: /* Split faces have 2 vertices and the same cells as the parent */
991: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
992: PetscMalloc1((2 + maxSupportSize*2), &supportRef);
993: for (f = fStart; f < fEnd; ++f) {
994: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
996: for (r = 0; r < 2; ++r) {
997: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
998: const PetscInt *cone, *ornt, *support;
999: PetscInt coneNew[2], coneSize, c, supportSize, s;
1001: DMPlexGetCone(dm, f, &cone);
1002: coneNew[0] = vStartNew + (cone[0] - vStart);
1003: coneNew[1] = vStartNew + (cone[1] - vStart);
1004: coneNew[(r+1)%2] = newv;
1005: DMPlexSetCone(rdm, newp, coneNew);
1006: #if 1
1007: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1008: for (p = 0; p < 2; ++p) {
1009: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
1010: }
1011: #endif
1012: DMPlexGetSupportSize(dm, f, &supportSize);
1013: DMPlexGetSupport(dm, f, &support);
1014: for (s = 0; s < supportSize; ++s) {
1015: DMPlexGetConeSize(dm, support[s], &coneSize);
1016: DMPlexGetCone(dm, support[s], &cone);
1017: DMPlexGetConeOrientation(dm, support[s], &ornt);
1018: for (c = 0; c < coneSize; ++c) {
1019: if (cone[c] == f) break;
1020: }
1021: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
1022: }
1023: DMPlexSetSupport(rdm, newp, supportRef);
1024: #if 1
1025: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1026: for (p = 0; p < supportSize; ++p) {
1027: if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
1028: }
1029: #endif
1030: }
1031: }
1032: /* Interior faces have 2 vertices and 2 cells */
1033: for (c = cStart; c < cEnd; ++c) {
1034: const PetscInt *cone;
1036: DMPlexGetCone(dm, c, &cone);
1037: for (r = 0; r < 3; ++r) {
1038: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
1039: PetscInt coneNew[2];
1040: PetscInt supportNew[2];
1042: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1043: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
1044: DMPlexSetCone(rdm, newp, coneNew);
1045: #if 1
1046: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1047: for (p = 0; p < 2; ++p) {
1048: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
1049: }
1050: #endif
1051: supportNew[0] = (c - cStart)*4 + (r+1)%3;
1052: supportNew[1] = (c - cStart)*4 + 3;
1053: DMPlexSetSupport(rdm, newp, supportNew);
1054: #if 1
1055: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1056: for (p = 0; p < 2; ++p) {
1057: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
1058: }
1059: #endif
1060: }
1061: }
1062: /* Old vertices have identical supports */
1063: for (v = vStart; v < vEnd; ++v) {
1064: const PetscInt newp = vStartNew + (v - vStart);
1065: const PetscInt *support, *cone;
1066: PetscInt size, s;
1068: DMPlexGetSupportSize(dm, v, &size);
1069: DMPlexGetSupport(dm, v, &support);
1070: for (s = 0; s < size; ++s) {
1071: PetscInt r = 0;
1073: DMPlexGetCone(dm, support[s], &cone);
1074: if (cone[1] == v) r = 1;
1075: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
1076: }
1077: DMPlexSetSupport(rdm, newp, supportRef);
1078: #if 1
1079: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1080: for (p = 0; p < size; ++p) {
1081: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
1082: }
1083: #endif
1084: }
1085: /* Face vertices have 2 + cells*2 supports */
1086: for (f = fStart; f < fEnd; ++f) {
1087: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
1088: const PetscInt *cone, *support;
1089: PetscInt size, s;
1091: DMPlexGetSupportSize(dm, f, &size);
1092: DMPlexGetSupport(dm, f, &support);
1093: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
1094: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
1095: for (s = 0; s < size; ++s) {
1096: PetscInt r = 0;
1098: DMPlexGetCone(dm, support[s], &cone);
1099: if (cone[1] == f) r = 1;
1100: else if (cone[2] == f) r = 2;
1101: supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
1102: supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
1103: }
1104: DMPlexSetSupport(rdm, newp, supportRef);
1105: #if 1
1106: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1107: for (p = 0; p < 2+size*2; ++p) {
1108: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
1109: }
1110: #endif
1111: }
1112: PetscFree(supportRef);
1113: break;
1114: case 2:
1115: /* Hex 2D */
1116: /*
1117: 3---------2---------2
1118: | | |
1119: | D 2 C |
1120: | | |
1121: 3----3----0----1----1
1122: | | |
1123: | A 0 B |
1124: | | |
1125: 0---------0---------1
1126: */
1127: /* All cells have 4 faces */
1128: for (c = cStart; c < cEnd; ++c) {
1129: const PetscInt newp = (c - cStart)*4;
1130: const PetscInt *cone, *ornt;
1131: PetscInt coneNew[4], orntNew[4];
1133: DMPlexGetCone(dm, c, &cone);
1134: DMPlexGetConeOrientation(dm, c, &ornt);
1135: /* A quad */
1136: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1137: orntNew[0] = ornt[0];
1138: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0;
1139: orntNew[1] = 0;
1140: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3;
1141: orntNew[2] = -2;
1142: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
1143: orntNew[3] = ornt[3];
1144: DMPlexSetCone(rdm, newp+0, coneNew);
1145: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
1146: #if 1
1147: if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
1148: for (p = 0; p < 4; ++p) {
1149: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1150: }
1151: #endif
1152: /* B quad */
1153: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1154: orntNew[0] = ornt[0];
1155: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1156: orntNew[1] = ornt[1];
1157: coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1;
1158: orntNew[2] = 0;
1159: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0;
1160: orntNew[3] = -2;
1161: DMPlexSetCone(rdm, newp+1, coneNew);
1162: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
1163: #if 1
1164: if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
1165: for (p = 0; p < 4; ++p) {
1166: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1167: }
1168: #endif
1169: /* C quad */
1170: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1;
1171: orntNew[0] = -2;
1172: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1173: orntNew[1] = ornt[1];
1174: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1175: orntNew[2] = ornt[2];
1176: coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2;
1177: orntNew[3] = 0;
1178: DMPlexSetCone(rdm, newp+2, coneNew);
1179: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
1180: #if 1
1181: if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
1182: for (p = 0; p < 4; ++p) {
1183: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1184: }
1185: #endif
1186: /* D quad */
1187: coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3;
1188: orntNew[0] = 0;
1189: coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2;
1190: orntNew[1] = -2;
1191: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1192: orntNew[2] = ornt[2];
1193: coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
1194: orntNew[3] = ornt[3];
1195: DMPlexSetCone(rdm, newp+3, coneNew);
1196: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
1197: #if 1
1198: if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
1199: for (p = 0; p < 4; ++p) {
1200: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1201: }
1202: #endif
1203: }
1204: /* Split faces have 2 vertices and the same cells as the parent */
1205: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
1206: PetscMalloc1((2 + maxSupportSize*2), &supportRef);
1207: for (f = fStart; f < fEnd; ++f) {
1208: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1210: for (r = 0; r < 2; ++r) {
1211: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
1212: const PetscInt *cone, *ornt, *support;
1213: PetscInt coneNew[2], coneSize, c, supportSize, s;
1215: DMPlexGetCone(dm, f, &cone);
1216: coneNew[0] = vStartNew + (cone[0] - vStart);
1217: coneNew[1] = vStartNew + (cone[1] - vStart);
1218: coneNew[(r+1)%2] = newv;
1219: DMPlexSetCone(rdm, newp, coneNew);
1220: #if 1
1221: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1222: for (p = 0; p < 2; ++p) {
1223: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
1224: }
1225: #endif
1226: DMPlexGetSupportSize(dm, f, &supportSize);
1227: DMPlexGetSupport(dm, f, &support);
1228: for (s = 0; s < supportSize; ++s) {
1229: DMPlexGetConeSize(dm, support[s], &coneSize);
1230: DMPlexGetCone(dm, support[s], &cone);
1231: DMPlexGetConeOrientation(dm, support[s], &ornt);
1232: for (c = 0; c < coneSize; ++c) {
1233: if (cone[c] == f) break;
1234: }
1235: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
1236: }
1237: DMPlexSetSupport(rdm, newp, supportRef);
1238: #if 1
1239: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1240: for (p = 0; p < supportSize; ++p) {
1241: if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
1242: }
1243: #endif
1244: }
1245: }
1246: /* Interior faces have 2 vertices and 2 cells */
1247: for (c = cStart; c < cEnd; ++c) {
1248: const PetscInt *cone;
1249: PetscInt coneNew[2], supportNew[2];
1251: DMPlexGetCone(dm, c, &cone);
1252: for (r = 0; r < 4; ++r) {
1253: const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
1255: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1256: coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
1257: DMPlexSetCone(rdm, newp, coneNew);
1258: #if 1
1259: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1260: for (p = 0; p < 2; ++p) {
1261: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
1262: }
1263: #endif
1264: supportNew[0] = (c - cStart)*4 + r;
1265: supportNew[1] = (c - cStart)*4 + (r+1)%4;
1266: DMPlexSetSupport(rdm, newp, supportNew);
1267: #if 1
1268: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1269: for (p = 0; p < 2; ++p) {
1270: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
1271: }
1272: #endif
1273: }
1274: }
1275: /* Old vertices have identical supports */
1276: for (v = vStart; v < vEnd; ++v) {
1277: const PetscInt newp = vStartNew + (v - vStart);
1278: const PetscInt *support, *cone;
1279: PetscInt size, s;
1281: DMPlexGetSupportSize(dm, v, &size);
1282: DMPlexGetSupport(dm, v, &support);
1283: for (s = 0; s < size; ++s) {
1284: PetscInt r = 0;
1286: DMPlexGetCone(dm, support[s], &cone);
1287: if (cone[1] == v) r = 1;
1288: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
1289: }
1290: DMPlexSetSupport(rdm, newp, supportRef);
1291: #if 1
1292: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1293: for (p = 0; p < size; ++p) {
1294: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
1295: }
1296: #endif
1297: }
1298: /* Face vertices have 2 + cells supports */
1299: for (f = fStart; f < fEnd; ++f) {
1300: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
1301: const PetscInt *cone, *support;
1302: PetscInt size, s;
1304: DMPlexGetSupportSize(dm, f, &size);
1305: DMPlexGetSupport(dm, f, &support);
1306: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
1307: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
1308: for (s = 0; s < size; ++s) {
1309: PetscInt r = 0;
1311: DMPlexGetCone(dm, support[s], &cone);
1312: if (cone[1] == f) r = 1;
1313: else if (cone[2] == f) r = 2;
1314: else if (cone[3] == f) r = 3;
1315: supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
1316: }
1317: DMPlexSetSupport(rdm, newp, supportRef);
1318: #if 1
1319: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1320: for (p = 0; p < 2+size; ++p) {
1321: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
1322: }
1323: #endif
1324: }
1325: /* Cell vertices have 4 supports */
1326: for (c = cStart; c < cEnd; ++c) {
1327: const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
1328: PetscInt supportNew[4];
1330: for (r = 0; r < 4; ++r) {
1331: supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
1332: }
1333: DMPlexSetSupport(rdm, newp, supportNew);
1334: }
1335: PetscFree(supportRef);
1336: break;
1337: case 3:
1338: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1339: cMax = PetscMin(cEnd, cMax);
1340: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
1341: fMax = PetscMin(fEnd, fMax);
1342: /* Interior cells have 3 faces */
1343: for (c = cStart; c < cMax; ++c) {
1344: const PetscInt newp = cStartNew + (c - cStart)*4;
1345: const PetscInt *cone, *ornt;
1346: PetscInt coneNew[3], orntNew[3];
1348: DMPlexGetCone(dm, c, &cone);
1349: DMPlexGetConeOrientation(dm, c, &ornt);
1350: /* A triangle */
1351: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1352: orntNew[0] = ornt[0];
1353: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2;
1354: orntNew[1] = -2;
1355: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1356: orntNew[2] = ornt[2];
1357: DMPlexSetCone(rdm, newp+0, coneNew);
1358: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
1359: #if 1
1360: if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
1361: for (p = 0; p < 3; ++p) {
1362: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1363: }
1364: #endif
1365: /* B triangle */
1366: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1367: orntNew[0] = ornt[0];
1368: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1369: orntNew[1] = ornt[1];
1370: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0;
1371: orntNew[2] = -2;
1372: DMPlexSetCone(rdm, newp+1, coneNew);
1373: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
1374: #if 1
1375: if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
1376: for (p = 0; p < 3; ++p) {
1377: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1378: }
1379: #endif
1380: /* C triangle */
1381: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1;
1382: orntNew[0] = -2;
1383: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1384: orntNew[1] = ornt[1];
1385: coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1386: orntNew[2] = ornt[2];
1387: DMPlexSetCone(rdm, newp+2, coneNew);
1388: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
1389: #if 1
1390: if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
1391: for (p = 0; p < 3; ++p) {
1392: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1393: }
1394: #endif
1395: /* D triangle */
1396: coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0;
1397: orntNew[0] = 0;
1398: coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1;
1399: orntNew[1] = 0;
1400: coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2;
1401: orntNew[2] = 0;
1402: DMPlexSetCone(rdm, newp+3, coneNew);
1403: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
1404: #if 1
1405: if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
1406: for (p = 0; p < 3; ++p) {
1407: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1408: }
1409: #endif
1410: }
1411: /*
1412: 2----3----3
1413: | |
1414: | B |
1415: | |
1416: 0----4--- 1
1417: | |
1418: | A |
1419: | |
1420: 0----2----1
1421: */
1422: /* Hybrid cells have 4 faces */
1423: for (c = cMax; c < cEnd; ++c) {
1424: const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
1425: const PetscInt *cone, *ornt;
1426: PetscInt coneNew[4], orntNew[4];
1428: DMPlexGetCone(dm, c, &cone);
1429: DMPlexGetConeOrientation(dm, c, &ornt);
1430: /* A quad */
1431: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1432: orntNew[0] = ornt[0];
1433: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1434: orntNew[1] = ornt[1];
1435: coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax);
1436: orntNew[2] = 0;
1437: coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
1438: orntNew[3] = 0;
1439: DMPlexSetCone(rdm, newp+0, coneNew);
1440: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
1441: #if 1
1442: if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
1443: for (p = 0; p < 4; ++p) {
1444: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1445: }
1446: #endif
1447: /* B quad */
1448: coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1449: orntNew[0] = ornt[0];
1450: coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1451: orntNew[1] = ornt[1];
1452: coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
1453: orntNew[2] = 0;
1454: coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax);
1455: orntNew[3] = 0;
1456: DMPlexSetCone(rdm, newp+1, coneNew);
1457: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
1458: #if 1
1459: if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
1460: for (p = 0; p < 4; ++p) {
1461: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1462: }
1463: #endif
1464: }
1465: /* Interior split faces have 2 vertices and the same cells as the parent */
1466: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
1467: PetscMalloc1((2 + maxSupportSize*2), &supportRef);
1468: for (f = fStart; f < fMax; ++f) {
1469: const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1471: for (r = 0; r < 2; ++r) {
1472: const PetscInt newp = fStartNew + (f - fStart)*2 + r;
1473: const PetscInt *cone, *ornt, *support;
1474: PetscInt coneNew[2], coneSize, c, supportSize, s;
1476: DMPlexGetCone(dm, f, &cone);
1477: coneNew[0] = vStartNew + (cone[0] - vStart);
1478: coneNew[1] = vStartNew + (cone[1] - vStart);
1479: coneNew[(r+1)%2] = newv;
1480: DMPlexSetCone(rdm, newp, coneNew);
1481: #if 1
1482: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1483: for (p = 0; p < 2; ++p) {
1484: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
1485: }
1486: #endif
1487: DMPlexGetSupportSize(dm, f, &supportSize);
1488: DMPlexGetSupport(dm, f, &support);
1489: for (s = 0; s < supportSize; ++s) {
1490: if (support[s] >= cMax) {
1491: supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
1492: } else {
1493: DMPlexGetConeSize(dm, support[s], &coneSize);
1494: DMPlexGetCone(dm, support[s], &cone);
1495: DMPlexGetConeOrientation(dm, support[s], &ornt);
1496: for (c = 0; c < coneSize; ++c) {
1497: if (cone[c] == f) break;
1498: }
1499: supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
1500: }
1501: }
1502: DMPlexSetSupport(rdm, newp, supportRef);
1503: #if 1
1504: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1505: for (p = 0; p < supportSize; ++p) {
1506: if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
1507: }
1508: #endif
1509: }
1510: }
1511: /* Interior cell faces have 2 vertices and 2 cells */
1512: for (c = cStart; c < cMax; ++c) {
1513: const PetscInt *cone;
1515: DMPlexGetCone(dm, c, &cone);
1516: for (r = 0; r < 3; ++r) {
1517: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
1518: PetscInt coneNew[2];
1519: PetscInt supportNew[2];
1521: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1522: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
1523: DMPlexSetCone(rdm, newp, coneNew);
1524: #if 1
1525: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1526: for (p = 0; p < 2; ++p) {
1527: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
1528: }
1529: #endif
1530: supportNew[0] = (c - cStart)*4 + (r+1)%3;
1531: supportNew[1] = (c - cStart)*4 + 3;
1532: DMPlexSetSupport(rdm, newp, supportNew);
1533: #if 1
1534: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1535: for (p = 0; p < 2; ++p) {
1536: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
1537: }
1538: #endif
1539: }
1540: }
1541: /* Interior hybrid faces have 2 vertices and the same cells */
1542: for (f = fMax; f < fEnd; ++f) {
1543: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
1544: const PetscInt *cone;
1545: const PetscInt *support;
1546: PetscInt coneNew[2];
1547: PetscInt supportNew[2];
1548: PetscInt size, s, r;
1550: DMPlexGetCone(dm, f, &cone);
1551: coneNew[0] = vStartNew + (cone[0] - vStart);
1552: coneNew[1] = vStartNew + (cone[1] - vStart);
1553: DMPlexSetCone(rdm, newp, coneNew);
1554: #if 1
1555: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1556: for (p = 0; p < 2; ++p) {
1557: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
1558: }
1559: #endif
1560: DMPlexGetSupportSize(dm, f, &size);
1561: DMPlexGetSupport(dm, f, &support);
1562: for (s = 0; s < size; ++s) {
1563: DMPlexGetCone(dm, support[s], &cone);
1564: for (r = 0; r < 2; ++r) {
1565: if (cone[r+2] == f) break;
1566: }
1567: supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
1568: }
1569: DMPlexSetSupport(rdm, newp, supportNew);
1570: #if 1
1571: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1572: for (p = 0; p < size; ++p) {
1573: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
1574: }
1575: #endif
1576: }
1577: /* Cell hybrid faces have 2 vertices and 2 cells */
1578: for (c = cMax; c < cEnd; ++c) {
1579: const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
1580: const PetscInt *cone;
1581: PetscInt coneNew[2];
1582: PetscInt supportNew[2];
1584: DMPlexGetCone(dm, c, &cone);
1585: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
1586: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
1587: DMPlexSetCone(rdm, newp, coneNew);
1588: #if 1
1589: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1590: for (p = 0; p < 2; ++p) {
1591: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
1592: }
1593: #endif
1594: supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
1595: supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
1596: DMPlexSetSupport(rdm, newp, supportNew);
1597: #if 1
1598: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1599: for (p = 0; p < 2; ++p) {
1600: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
1601: }
1602: #endif
1603: }
1604: /* Old vertices have identical supports */
1605: for (v = vStart; v < vEnd; ++v) {
1606: const PetscInt newp = vStartNew + (v - vStart);
1607: const PetscInt *support, *cone;
1608: PetscInt size, s;
1610: DMPlexGetSupportSize(dm, v, &size);
1611: DMPlexGetSupport(dm, v, &support);
1612: for (s = 0; s < size; ++s) {
1613: if (support[s] >= fMax) {
1614: supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
1615: } else {
1616: PetscInt r = 0;
1618: DMPlexGetCone(dm, support[s], &cone);
1619: if (cone[1] == v) r = 1;
1620: supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
1621: }
1622: }
1623: DMPlexSetSupport(rdm, newp, supportRef);
1624: #if 1
1625: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1626: for (p = 0; p < size; ++p) {
1627: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
1628: }
1629: #endif
1630: }
1631: /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
1632: for (f = fStart; f < fMax; ++f) {
1633: const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
1634: const PetscInt *cone, *support;
1635: PetscInt size, newSize = 2, s;
1637: DMPlexGetSupportSize(dm, f, &size);
1638: DMPlexGetSupport(dm, f, &support);
1639: supportRef[0] = fStartNew + (f - fStart)*2 + 0;
1640: supportRef[1] = fStartNew + (f - fStart)*2 + 1;
1641: for (s = 0; s < size; ++s) {
1642: PetscInt r = 0;
1644: DMPlexGetCone(dm, support[s], &cone);
1645: if (support[s] >= cMax) {
1646: supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
1648: newSize += 1;
1649: } else {
1650: if (cone[1] == f) r = 1;
1651: else if (cone[2] == f) r = 2;
1652: supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
1653: supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
1655: newSize += 2;
1656: }
1657: }
1658: DMPlexSetSupport(rdm, newp, supportRef);
1659: #if 1
1660: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1661: for (p = 0; p < newSize; ++p) {
1662: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
1663: }
1664: #endif
1665: }
1666: PetscFree(supportRef);
1667: break;
1668: case 5:
1669: /* Simplicial 3D */
1670: /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
1671: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
1672: for (c = cStart; c < cEnd; ++c) {
1673: const PetscInt newp = cStartNew + (c - cStart)*8;
1674: const PetscInt *cone, *ornt;
1675: PetscInt coneNew[4], orntNew[4];
1677: DMPlexGetCone(dm, c, &cone);
1678: DMPlexGetConeOrientation(dm, c, &ornt);
1679: /* A tetrahedron: {0, a, c, d} */
1680: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
1681: orntNew[0] = ornt[0];
1682: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
1683: orntNew[1] = ornt[1];
1684: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
1685: orntNew[2] = ornt[2];
1686: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0;
1687: orntNew[3] = 0;
1688: DMPlexSetCone(rdm, newp+0, coneNew);
1689: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
1690: #if 1
1691: if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
1692: for (p = 0; p < 4; ++p) {
1693: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1694: }
1695: #endif
1696: /* B tetrahedron: {a, 1, b, e} */
1697: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
1698: orntNew[0] = ornt[0];
1699: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
1700: orntNew[1] = ornt[1];
1701: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1;
1702: orntNew[2] = 0;
1703: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
1704: orntNew[3] = ornt[3];
1705: DMPlexSetCone(rdm, newp+1, coneNew);
1706: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
1707: #if 1
1708: if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
1709: for (p = 0; p < 4; ++p) {
1710: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1711: }
1712: #endif
1713: /* C tetrahedron: {c, b, 2, f} */
1714: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
1715: orntNew[0] = ornt[0];
1716: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2;
1717: orntNew[1] = 0;
1718: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
1719: orntNew[2] = ornt[2];
1720: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
1721: orntNew[3] = ornt[3];
1722: DMPlexSetCone(rdm, newp+2, coneNew);
1723: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
1724: #if 1
1725: if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
1726: for (p = 0; p < 4; ++p) {
1727: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1728: }
1729: #endif
1730: /* D tetrahedron: {d, e, f, 3} */
1731: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3;
1732: orntNew[0] = 0;
1733: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
1734: orntNew[1] = ornt[1];
1735: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
1736: orntNew[2] = ornt[2];
1737: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
1738: orntNew[3] = ornt[3];
1739: DMPlexSetCone(rdm, newp+3, coneNew);
1740: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
1741: #if 1
1742: if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
1743: for (p = 0; p < 4; ++p) {
1744: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1745: }
1746: #endif
1747: /* A' tetrahedron: {d, a, c, f} */
1748: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0;
1749: orntNew[0] = -3;
1750: coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
1751: orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
1752: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
1753: orntNew[2] = 0;
1754: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
1755: orntNew[3] = 2;
1756: DMPlexSetCone(rdm, newp+4, coneNew);
1757: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
1758: #if 1
1759: if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew);
1760: for (p = 0; p < 4; ++p) {
1761: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1762: }
1763: #endif
1764: /* B' tetrahedron: {e, b, a, f} */
1765: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1;
1766: orntNew[0] = -3;
1767: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
1768: orntNew[1] = 1;
1769: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
1770: orntNew[2] = 0;
1771: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
1772: orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
1773: DMPlexSetCone(rdm, newp+5, coneNew);
1774: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
1775: #if 1
1776: if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew);
1777: for (p = 0; p < 4; ++p) {
1778: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1779: }
1780: #endif
1781: /* C' tetrahedron: {b, f, c, a} */
1782: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2;
1783: orntNew[0] = -3;
1784: coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
1785: orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
1786: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
1787: orntNew[2] = -3;
1788: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
1789: orntNew[3] = -2;
1790: DMPlexSetCone(rdm, newp+6, coneNew);
1791: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
1792: #if 1
1793: if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew);
1794: for (p = 0; p < 4; ++p) {
1795: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1796: }
1797: #endif
1798: /* D' tetrahedron: {f, e, d, a} */
1799: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3;
1800: orntNew[0] = -3;
1801: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
1802: orntNew[1] = -3;
1803: coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
1804: orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
1805: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
1806: orntNew[3] = -3;
1807: DMPlexSetCone(rdm, newp+7, coneNew);
1808: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
1809: #if 1
1810: if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew);
1811: for (p = 0; p < 4; ++p) {
1812: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1813: }
1814: #endif
1815: }
1816: /* Split faces have 3 edges and the same cells as the parent */
1817: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
1818: PetscMalloc1((2 + maxSupportSize*2), &supportRef);
1819: for (f = fStart; f < fEnd; ++f) {
1820: const PetscInt newp = fStartNew + (f - fStart)*4;
1821: const PetscInt *cone, *ornt, *support;
1822: PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s;
1824: DMPlexGetCone(dm, f, &cone);
1825: DMPlexGetConeOrientation(dm, f, &ornt);
1826: /* A triangle */
1827: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
1828: orntNew[0] = ornt[0];
1829: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
1830: orntNew[1] = -2;
1831: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
1832: orntNew[2] = ornt[2];
1833: DMPlexSetCone(rdm, newp+0, coneNew);
1834: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
1835: #if 1
1836: if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fEndNew);
1837: for (p = 0; p < 3; ++p) {
1838: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
1839: }
1840: #endif
1841: /* B triangle */
1842: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
1843: orntNew[0] = ornt[0];
1844: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
1845: orntNew[1] = ornt[1];
1846: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
1847: orntNew[2] = -2;
1848: DMPlexSetCone(rdm, newp+1, coneNew);
1849: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
1850: #if 1
1851: if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew);
1852: for (p = 0; p < 3; ++p) {
1853: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
1854: }
1855: #endif
1856: /* C triangle */
1857: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
1858: orntNew[0] = -2;
1859: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
1860: orntNew[1] = ornt[1];
1861: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
1862: orntNew[2] = ornt[2];
1863: DMPlexSetCone(rdm, newp+2, coneNew);
1864: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
1865: #if 1
1866: if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fEndNew);
1867: for (p = 0; p < 3; ++p) {
1868: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
1869: }
1870: #endif
1871: /* D triangle */
1872: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
1873: orntNew[0] = 0;
1874: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
1875: orntNew[1] = 0;
1876: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
1877: orntNew[2] = 0;
1878: DMPlexSetCone(rdm, newp+3, coneNew);
1879: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
1880: #if 1
1881: if ((newp+3 < fStartNew) || (newp+3 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fEndNew);
1882: for (p = 0; p < 3; ++p) {
1883: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
1884: }
1885: #endif
1886: DMPlexGetSupportSize(dm, f, &supportSize);
1887: DMPlexGetSupport(dm, f, &support);
1888: for (r = 0; r < 4; ++r) {
1889: for (s = 0; s < supportSize; ++s) {
1890: PetscInt subf;
1891: DMPlexGetConeSize(dm, support[s], &coneSize);
1892: DMPlexGetCone(dm, support[s], &cone);
1893: DMPlexGetConeOrientation(dm, support[s], &ornt);
1894: for (c = 0; c < coneSize; ++c) {
1895: if (cone[c] == f) break;
1896: }
1897: subf = GetTriSubfaceInverse_Static(ornt[c], r);
1898: supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
1899: }
1900: DMPlexSetSupport(rdm, newp+r, supportRef);
1901: #if 1
1902: if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fEndNew);
1903: for (p = 0; p < supportSize; ++p) {
1904: if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
1905: }
1906: #endif
1907: }
1908: }
1909: /* Interior faces have 3 edges and 2 cells */
1910: for (c = cStart; c < cEnd; ++c) {
1911: PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
1912: const PetscInt *cone, *ornt;
1913: PetscInt coneNew[3], orntNew[3];
1914: PetscInt supportNew[2];
1916: DMPlexGetCone(dm, c, &cone);
1917: DMPlexGetConeOrientation(dm, c, &ornt);
1918: /* Face A: {c, a, d} */
1919: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
1920: orntNew[0] = ornt[0] < 0 ? -2 : 0;
1921: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
1922: orntNew[1] = ornt[1] < 0 ? -2 : 0;
1923: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
1924: orntNew[2] = ornt[2] < 0 ? -2 : 0;
1925: DMPlexSetCone(rdm, newp, coneNew);
1926: DMPlexSetConeOrientation(rdm, newp, orntNew);
1927: #if 1
1928: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1929: for (p = 0; p < 3; ++p) {
1930: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
1931: }
1932: #endif
1933: supportNew[0] = (c - cStart)*8 + 0;
1934: supportNew[1] = (c - cStart)*8 + 0+4;
1935: DMPlexSetSupport(rdm, newp, supportNew);
1936: #if 1
1937: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1938: for (p = 0; p < 2; ++p) {
1939: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
1940: }
1941: #endif
1942: ++newp;
1943: /* Face B: {a, b, e} */
1944: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
1945: orntNew[0] = ornt[0] < 0 ? -2 : 0;
1946: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
1947: orntNew[1] = ornt[3] < 0 ? -2 : 0;
1948: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
1949: orntNew[2] = ornt[1] < 0 ? -2 : 0;
1950: DMPlexSetCone(rdm, newp, coneNew);
1951: DMPlexSetConeOrientation(rdm, newp, orntNew);
1952: #if 1
1953: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1954: for (p = 0; p < 3; ++p) {
1955: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
1956: }
1957: #endif
1958: supportNew[0] = (c - cStart)*8 + 1;
1959: supportNew[1] = (c - cStart)*8 + 1+4;
1960: DMPlexSetSupport(rdm, newp, supportNew);
1961: #if 1
1962: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1963: for (p = 0; p < 2; ++p) {
1964: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
1965: }
1966: #endif
1967: ++newp;
1968: /* Face C: {c, f, b} */
1969: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
1970: orntNew[0] = ornt[2] < 0 ? -2 : 0;
1971: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
1972: orntNew[1] = ornt[3] < 0 ? -2 : 0;
1973: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
1974: orntNew[2] = ornt[0] < 0 ? -2 : 0;
1975: DMPlexSetCone(rdm, newp, coneNew);
1976: DMPlexSetConeOrientation(rdm, newp, orntNew);
1977: #if 1
1978: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1979: for (p = 0; p < 3; ++p) {
1980: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
1981: }
1982: #endif
1983: supportNew[0] = (c - cStart)*8 + 2;
1984: supportNew[1] = (c - cStart)*8 + 2+4;
1985: DMPlexSetSupport(rdm, newp, supportNew);
1986: #if 1
1987: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1988: for (p = 0; p < 2; ++p) {
1989: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
1990: }
1991: #endif
1992: ++newp;
1993: /* Face D: {d, e, f} */
1994: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
1995: orntNew[0] = ornt[1] < 0 ? -2 : 0;
1996: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
1997: orntNew[1] = ornt[3] < 0 ? -2 : 0;
1998: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
1999: orntNew[2] = ornt[2] < 0 ? -2 : 0;
2000: DMPlexSetCone(rdm, newp, coneNew);
2001: DMPlexSetConeOrientation(rdm, newp, orntNew);
2002: #if 1
2003: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2004: for (p = 0; p < 3; ++p) {
2005: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2006: }
2007: #endif
2008: supportNew[0] = (c - cStart)*8 + 3;
2009: supportNew[1] = (c - cStart)*8 + 3+4;
2010: DMPlexSetSupport(rdm, newp, supportNew);
2011: #if 1
2012: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2013: for (p = 0; p < 2; ++p) {
2014: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2015: }
2016: #endif
2017: ++newp;
2018: /* Face E: {d, f, a} */
2019: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2020: orntNew[0] = ornt[2] < 0 ? 0 : -2;
2021: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2022: orntNew[1] = -2;
2023: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2024: orntNew[2] = ornt[1] < 0 ? -2 : 0;
2025: DMPlexSetCone(rdm, newp, coneNew);
2026: DMPlexSetConeOrientation(rdm, newp, orntNew);
2027: #if 1
2028: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2029: for (p = 0; p < 3; ++p) {
2030: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2031: }
2032: #endif
2033: supportNew[0] = (c - cStart)*8 + 0+4;
2034: supportNew[1] = (c - cStart)*8 + 3+4;
2035: DMPlexSetSupport(rdm, newp, supportNew);
2036: #if 1
2037: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2038: for (p = 0; p < 2; ++p) {
2039: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2040: }
2041: #endif
2042: ++newp;
2043: /* Face F: {c, a, f} */
2044: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2045: orntNew[0] = ornt[0] < 0 ? -2 : 0;
2046: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2047: orntNew[1] = 0;
2048: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
2049: orntNew[2] = ornt[2] < 0 ? 0 : -2;
2050: DMPlexSetCone(rdm, newp, coneNew);
2051: DMPlexSetConeOrientation(rdm, newp, orntNew);
2052: #if 1
2053: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2054: for (p = 0; p < 3; ++p) {
2055: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2056: }
2057: #endif
2058: supportNew[0] = (c - cStart)*8 + 0+4;
2059: supportNew[1] = (c - cStart)*8 + 2+4;
2060: DMPlexSetSupport(rdm, newp, supportNew);
2061: #if 1
2062: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2063: for (p = 0; p < 2; ++p) {
2064: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2065: }
2066: #endif
2067: ++newp;
2068: /* Face G: {e, a, f} */
2069: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2070: orntNew[0] = ornt[1] < 0 ? -2 : 0;
2071: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2072: orntNew[1] = 0;
2073: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2074: orntNew[2] = ornt[3] < 0 ? 0 : -2;
2075: DMPlexSetCone(rdm, newp, coneNew);
2076: DMPlexSetConeOrientation(rdm, newp, orntNew);
2077: #if 1
2078: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2079: for (p = 0; p < 3; ++p) {
2080: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2081: }
2082: #endif
2083: supportNew[0] = (c - cStart)*8 + 1+4;
2084: supportNew[1] = (c - cStart)*8 + 3+4;
2085: DMPlexSetSupport(rdm, newp, supportNew);
2086: #if 1
2087: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2088: for (p = 0; p < 2; ++p) {
2089: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2090: }
2091: #endif
2092: ++newp;
2093: /* Face H: {a, b, f} */
2094: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2095: orntNew[0] = ornt[0] < 0 ? -2 : 0;
2096: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2097: orntNew[1] = ornt[3] < 0 ? 0 : -2;
2098: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2099: orntNew[2] = -2;
2100: DMPlexSetCone(rdm, newp, coneNew);
2101: DMPlexSetConeOrientation(rdm, newp, orntNew);
2102: #if 1
2103: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2104: for (p = 0; p < 3; ++p) {
2105: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2106: }
2107: #endif
2108: supportNew[0] = (c - cStart)*8 + 1+4;
2109: supportNew[1] = (c - cStart)*8 + 2+4;
2110: DMPlexSetSupport(rdm, newp, supportNew);
2111: #if 1
2112: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2113: for (p = 0; p < 2; ++p) {
2114: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2115: }
2116: #endif
2117: ++newp;
2118: }
2119: /* Split Edges have 2 vertices and the same faces as the parent */
2120: for (e = eStart; e < eEnd; ++e) {
2121: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2123: for (r = 0; r < 2; ++r) {
2124: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
2125: const PetscInt *cone, *ornt, *support;
2126: PetscInt coneNew[2], coneSize, c, supportSize, s;
2128: DMPlexGetCone(dm, e, &cone);
2129: coneNew[0] = vStartNew + (cone[0] - vStart);
2130: coneNew[1] = vStartNew + (cone[1] - vStart);
2131: coneNew[(r+1)%2] = newv;
2132: DMPlexSetCone(rdm, newp, coneNew);
2133: #if 1
2134: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2135: for (p = 0; p < 2; ++p) {
2136: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2137: }
2138: #endif
2139: DMPlexGetSupportSize(dm, e, &supportSize);
2140: DMPlexGetSupport(dm, e, &support);
2141: for (s = 0; s < supportSize; ++s) {
2142: DMPlexGetConeSize(dm, support[s], &coneSize);
2143: DMPlexGetCone(dm, support[s], &cone);
2144: DMPlexGetConeOrientation(dm, support[s], &ornt);
2145: for (c = 0; c < coneSize; ++c) {
2146: if (cone[c] == e) break;
2147: }
2148: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2149: }
2150: DMPlexSetSupport(rdm, newp, supportRef);
2151: #if 1
2152: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2153: for (p = 0; p < supportSize; ++p) {
2154: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
2155: }
2156: #endif
2157: }
2158: }
2159: /* Face edges have 2 vertices and 2+cells*(1/2) faces */
2160: for (f = fStart; f < fEnd; ++f) {
2161: const PetscInt *cone, *ornt, *support;
2162: PetscInt coneSize, supportSize, s;
2164: DMPlexGetSupportSize(dm, f, &supportSize);
2165: DMPlexGetSupport(dm, f, &support);
2166: for (r = 0; r < 3; ++r) {
2167: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2168: PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2169: PetscInt fint[24] = { 1, 7, -1, -1, 0, 5,
2170: -1, -1, 1, 6, 0, 4,
2171: 2, 5, 3, 4, -1, -1,
2172: -1, -1, 3, 6, 2, 7};
2174: DMPlexGetCone(dm, f, &cone);
2175: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2176: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2177: DMPlexSetCone(rdm, newp, coneNew);
2178: #if 1
2179: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2180: for (p = 0; p < 2; ++p) {
2181: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2182: }
2183: #endif
2184: supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2185: supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2186: for (s = 0; s < supportSize; ++s) {
2187: DMPlexGetConeSize(dm, support[s], &coneSize);
2188: DMPlexGetCone(dm, support[s], &cone);
2189: DMPlexGetConeOrientation(dm, support[s], &ornt);
2190: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
2191: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
2192: er = GetTetSomethingInverse_Static(ornt[c], r);
2193: if (er == eint[c]) {
2194: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2195: } else {
2196: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2197: supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2198: }
2199: }
2200: DMPlexSetSupport(rdm, newp, supportRef);
2201: #if 1
2202: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2203: for (p = 0; p < intFaces; ++p) {
2204: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
2205: }
2206: #endif
2207: }
2208: }
2209: /* Interior edges have 2 vertices and 4 faces */
2210: for (c = cStart; c < cEnd; ++c) {
2211: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2212: const PetscInt *cone, *ornt, *fcone;
2213: PetscInt coneNew[2], supportNew[4], find;
2215: DMPlexGetCone(dm, c, &cone);
2216: DMPlexGetConeOrientation(dm, c, &ornt);
2217: DMPlexGetCone(dm, cone[0], &fcone);
2218: find = GetTriEdge_Static(ornt[0], 0);
2219: coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2220: DMPlexGetCone(dm, cone[2], &fcone);
2221: find = GetTriEdge_Static(ornt[2], 1);
2222: coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2223: DMPlexSetCone(rdm, newp, coneNew);
2224: #if 1
2225: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2226: for (p = 0; p < 2; ++p) {
2227: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2228: }
2229: #endif
2230: supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2231: supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2232: supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2233: supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2234: DMPlexSetSupport(rdm, newp, supportNew);
2235: #if 1
2236: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2237: for (p = 0; p < 4; ++p) {
2238: if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew);
2239: }
2240: #endif
2241: }
2242: /* Old vertices have identical supports */
2243: for (v = vStart; v < vEnd; ++v) {
2244: const PetscInt newp = vStartNew + (v - vStart);
2245: const PetscInt *support, *cone;
2246: PetscInt size, s;
2248: DMPlexGetSupportSize(dm, v, &size);
2249: DMPlexGetSupport(dm, v, &support);
2250: for (s = 0; s < size; ++s) {
2251: PetscInt r = 0;
2253: DMPlexGetCone(dm, support[s], &cone);
2254: if (cone[1] == v) r = 1;
2255: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2256: }
2257: DMPlexSetSupport(rdm, newp, supportRef);
2258: #if 1
2259: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
2260: for (p = 0; p < size; ++p) {
2261: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
2262: }
2263: #endif
2264: }
2265: /* Edge vertices have 2 + face*2 + 0/1 supports */
2266: for (e = eStart; e < eEnd; ++e) {
2267: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
2268: const PetscInt *cone, *support;
2269: PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2271: DMPlexGetSupportSize(dm, e, &size);
2272: DMPlexGetSupport(dm, e, &support);
2273: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2274: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2275: for (s = 0; s < size; ++s) {
2276: PetscInt r = 0;
2278: DMPlexGetConeSize(dm, support[s], &coneSize);
2279: DMPlexGetCone(dm, support[s], &cone);
2280: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2281: supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2282: supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2283: }
2284: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
2285: for (s = 0; s < starSize*2; s += 2) {
2286: const PetscInt *cone, *ornt;
2287: PetscInt e01, e23;
2289: if ((star[s] >= cStart) && (star[s] < cEnd)) {
2290: /* Check edge 0-1 */
2291: DMPlexGetCone(dm, star[s], &cone);
2292: DMPlexGetConeOrientation(dm, star[s], &ornt);
2293: DMPlexGetCone(dm, cone[0], &cone);
2294: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
2295: /* Check edge 2-3 */
2296: DMPlexGetCone(dm, star[s], &cone);
2297: DMPlexGetConeOrientation(dm, star[s], &ornt);
2298: DMPlexGetCone(dm, cone[2], &cone);
2299: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
2300: if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2301: }
2302: }
2303: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
2304: DMPlexSetSupport(rdm, newp, supportRef);
2305: #if 1
2306: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
2307: for (p = 0; p < 2+size*2+cellSize; ++p) {
2308: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
2309: }
2310: #endif
2311: }
2312: PetscFree(supportRef);
2313: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
2314: break;
2315: case 7:
2316: /* Hybrid Simplicial 3D */
2317: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);
2318: /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2319: DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);
2320: for (c = cStart; c < cMax; ++c) {
2321: const PetscInt newp = cStartNew + (c - cStart)*8;
2322: const PetscInt *cone, *ornt;
2323: PetscInt coneNew[4], orntNew[4];
2325: DMPlexGetCone(dm, c, &cone);
2326: DMPlexGetConeOrientation(dm, c, &ornt);
2327: /* A tetrahedron: {0, a, c, d} */
2328: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2329: orntNew[0] = ornt[0];
2330: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2331: orntNew[1] = ornt[1];
2332: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2333: orntNew[2] = ornt[2];
2334: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0;
2335: orntNew[3] = 0;
2336: DMPlexSetCone(rdm, newp+0, coneNew);
2337: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2338: #if 1
2339: if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cMaxNew);
2340: for (p = 0; p < 4; ++p) {
2341: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2342: }
2343: #endif
2344: /* B tetrahedron: {a, 1, b, e} */
2345: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2346: orntNew[0] = ornt[0];
2347: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2348: orntNew[1] = ornt[1];
2349: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1;
2350: orntNew[2] = 0;
2351: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2352: orntNew[3] = ornt[3];
2353: DMPlexSetCone(rdm, newp+1, coneNew);
2354: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2355: #if 1
2356: if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cMaxNew);
2357: for (p = 0; p < 4; ++p) {
2358: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2359: }
2360: #endif
2361: /* C tetrahedron: {c, b, 2, f} */
2362: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2363: orntNew[0] = ornt[0];
2364: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2;
2365: orntNew[1] = 0;
2366: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2367: orntNew[2] = ornt[2];
2368: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2369: orntNew[3] = ornt[3];
2370: DMPlexSetCone(rdm, newp+2, coneNew);
2371: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2372: #if 1
2373: if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cMaxNew);
2374: for (p = 0; p < 4; ++p) {
2375: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2376: }
2377: #endif
2378: /* D tetrahedron: {d, e, f, 3} */
2379: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3;
2380: orntNew[0] = 0;
2381: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2382: orntNew[1] = ornt[1];
2383: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2384: orntNew[2] = ornt[2];
2385: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2386: orntNew[3] = ornt[3];
2387: DMPlexSetCone(rdm, newp+3, coneNew);
2388: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2389: #if 1
2390: if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cMaxNew);
2391: for (p = 0; p < 4; ++p) {
2392: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2393: }
2394: #endif
2395: /* A' tetrahedron: {d, a, c, f} */
2396: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0;
2397: orntNew[0] = -3;
2398: coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2399: orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
2400: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
2401: orntNew[2] = 0;
2402: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
2403: orntNew[3] = 2;
2404: DMPlexSetCone(rdm, newp+4, coneNew);
2405: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
2406: #if 1
2407: if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cMaxNew);
2408: for (p = 0; p < 4; ++p) {
2409: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2410: }
2411: #endif
2412: /* B' tetrahedron: {e, b, a, f} */
2413: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1;
2414: orntNew[0] = -3;
2415: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
2416: orntNew[1] = 1;
2417: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
2418: orntNew[2] = 0;
2419: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
2420: orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
2421: DMPlexSetCone(rdm, newp+5, coneNew);
2422: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
2423: #if 1
2424: if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cMaxNew);
2425: for (p = 0; p < 4; ++p) {
2426: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2427: }
2428: #endif
2429: /* C' tetrahedron: {b, f, c, a} */
2430: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2;
2431: orntNew[0] = -3;
2432: coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
2433: orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
2434: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
2435: orntNew[2] = -3;
2436: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
2437: orntNew[3] = -2;
2438: DMPlexSetCone(rdm, newp+6, coneNew);
2439: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
2440: #if 1
2441: if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cMaxNew);
2442: for (p = 0; p < 4; ++p) {
2443: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2444: }
2445: #endif
2446: /* D' tetrahedron: {f, e, d, a} */
2447: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3;
2448: orntNew[0] = -3;
2449: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
2450: orntNew[1] = -3;
2451: coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
2452: orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
2453: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
2454: orntNew[3] = -3;
2455: DMPlexSetCone(rdm, newp+7, coneNew);
2456: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
2457: #if 1
2458: if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cMaxNew);
2459: for (p = 0; p < 4; ++p) {
2460: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2461: }
2462: #endif
2463: }
2464: /* Hybrid cells have 5 faces */
2465: for (c = cMax; c < cEnd; ++c) {
2466: const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
2467: const PetscInt *cone, *ornt, *fornt;
2468: PetscInt coneNew[5], orntNew[5];
2470: DMPlexGetCone(dm, c, &cone);
2471: DMPlexGetConeOrientation(dm, c, &ornt);
2472: DMPlexGetConeOrientation(dm, cone[0], &fornt);
2473: for (r = 0; r < 3; ++r) {
2474: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
2475: orntNew[0] = ornt[0];
2476: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
2477: orntNew[1] = ornt[1];
2478: coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? 0 : 1);
2479: orntNew[2] = 0;
2480: coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? 1 : 0);
2481: orntNew[3] = 0;
2482: coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
2483: orntNew[4] = 0;
2484: DMPlexSetCone(rdm, newp+r, coneNew);
2485: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
2486: #if 1
2487: if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+r, cMaxNew, cEndNew);
2488: for (p = 0; p < 2; ++p) {
2489: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2490: }
2491: for (p = 2; p < 5; ++p) {
2492: if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew);
2493: }
2494: #endif
2495: }
2496: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
2497: orntNew[0] = 0;
2498: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
2499: orntNew[1] = 0;
2500: coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
2501: orntNew[2] = 0;
2502: coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
2503: orntNew[3] = 0;
2504: coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
2505: orntNew[4] = 0;
2506: DMPlexSetCone(rdm, newp+3, coneNew);
2507: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2508: #if 1
2509: if ((newp+3 < cMaxNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+3, cMaxNew, cEndNew);
2510: for (p = 0; p < 2; ++p) {
2511: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2512: }
2513: for (p = 2; p < 5; ++p) {
2514: if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew);
2515: }
2516: #endif
2517: }
2518: /* Split faces have 3 edges and the same cells as the parent */
2519: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
2520: PetscMalloc1((2 + maxSupportSize*2), &supportRef);
2521: for (f = fStart; f < fMax; ++f) {
2522: const PetscInt newp = fStartNew + (f - fStart)*4;
2523: const PetscInt *cone, *ornt, *support;
2524: PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s;
2526: DMPlexGetCone(dm, f, &cone);
2527: DMPlexGetConeOrientation(dm, f, &ornt);
2528: /* A triangle */
2529: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2530: orntNew[0] = ornt[0];
2531: coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
2532: orntNew[1] = -2;
2533: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2534: orntNew[2] = ornt[2];
2535: DMPlexSetCone(rdm, newp+0, coneNew);
2536: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
2537: #if 1
2538: if ((newp+0 < fStartNew) || (newp+0 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fMaxNew);
2539: for (p = 0; p < 3; ++p) {
2540: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2541: }
2542: #endif
2543: /* B triangle */
2544: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2545: orntNew[0] = ornt[0];
2546: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2547: orntNew[1] = ornt[1];
2548: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
2549: orntNew[2] = -2;
2550: DMPlexSetCone(rdm, newp+1, coneNew);
2551: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
2552: #if 1
2553: if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fMaxNew);
2554: for (p = 0; p < 3; ++p) {
2555: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2556: }
2557: #endif
2558: /* C triangle */
2559: coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
2560: orntNew[0] = -2;
2561: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2562: orntNew[1] = ornt[1];
2563: coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2564: orntNew[2] = ornt[2];
2565: DMPlexSetCone(rdm, newp+2, coneNew);
2566: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
2567: #if 1
2568: if ((newp+2 < fStartNew) || (newp+2 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fMaxNew);
2569: for (p = 0; p < 3; ++p) {
2570: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2571: }
2572: #endif
2573: /* D triangle */
2574: coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0;
2575: orntNew[0] = 0;
2576: coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1;
2577: orntNew[1] = 0;
2578: coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2;
2579: orntNew[2] = 0;
2580: DMPlexSetCone(rdm, newp+3, coneNew);
2581: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
2582: #if 1
2583: if ((newp+3 < fStartNew) || (newp+3 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fMaxNew);
2584: for (p = 0; p < 3; ++p) {
2585: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2586: }
2587: #endif
2588: DMPlexGetSupportSize(dm, f, &supportSize);
2589: DMPlexGetSupport(dm, f, &support);
2590: for (r = 0; r < 4; ++r) {
2591: for (s = 0; s < supportSize; ++s) {
2592: PetscInt subf;
2593: DMPlexGetConeSize(dm, support[s], &coneSize);
2594: DMPlexGetCone(dm, support[s], &cone);
2595: DMPlexGetConeOrientation(dm, support[s], &ornt);
2596: for (c = 0; c < coneSize; ++c) {
2597: if (cone[c] == f) break;
2598: }
2599: subf = GetTriSubfaceInverse_Static(ornt[c], r);
2600: if (support[s] < cMax) {
2601: supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2602: } else {
2603: supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
2604: }
2605: }
2606: DMPlexSetSupport(rdm, newp+r, supportRef);
2607: #if 1
2608: if ((newp+r < fStartNew) || (newp+r >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fMaxNew);
2609: for (p = 0; p < supportSize; ++p) {
2610: if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
2611: }
2612: #endif
2613: }
2614: }
2615: /* Interior cell faces have 3 edges and 2 cells */
2616: for (c = cStart; c < cMax; ++c) {
2617: PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
2618: const PetscInt *cone, *ornt;
2619: PetscInt coneNew[3], orntNew[3];
2620: PetscInt supportNew[2];
2622: DMPlexGetCone(dm, c, &cone);
2623: DMPlexGetConeOrientation(dm, c, &ornt);
2624: /* Face A: {c, a, d} */
2625: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2626: orntNew[0] = ornt[0] < 0 ? -2 : 0;
2627: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2628: orntNew[1] = ornt[1] < 0 ? -2 : 0;
2629: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
2630: orntNew[2] = ornt[2] < 0 ? -2 : 0;
2631: DMPlexSetCone(rdm, newp, coneNew);
2632: DMPlexSetConeOrientation(rdm, newp, orntNew);
2633: #if 1
2634: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2635: for (p = 0; p < 3; ++p) {
2636: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2637: }
2638: #endif
2639: supportNew[0] = (c - cStart)*8 + 0;
2640: supportNew[1] = (c - cStart)*8 + 0+4;
2641: DMPlexSetSupport(rdm, newp, supportNew);
2642: #if 1
2643: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2644: for (p = 0; p < 2; ++p) {
2645: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
2646: }
2647: #endif
2648: ++newp;
2649: /* Face B: {a, b, e} */
2650: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2651: orntNew[0] = ornt[0] < 0 ? -2 : 0;
2652: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
2653: orntNew[1] = ornt[3] < 0 ? -2 : 0;
2654: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2655: orntNew[2] = ornt[1] < 0 ? -2 : 0;
2656: DMPlexSetCone(rdm, newp, coneNew);
2657: DMPlexSetConeOrientation(rdm, newp, orntNew);
2658: #if 1
2659: if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fMaxNew);
2660: for (p = 0; p < 3; ++p) {
2661: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2662: }
2663: #endif
2664: supportNew[0] = (c - cStart)*8 + 1;
2665: supportNew[1] = (c - cStart)*8 + 1+4;
2666: DMPlexSetSupport(rdm, newp, supportNew);
2667: #if 1
2668: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2669: for (p = 0; p < 2; ++p) {
2670: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
2671: }
2672: #endif
2673: ++newp;
2674: /* Face C: {c, f, b} */
2675: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
2676: orntNew[0] = ornt[2] < 0 ? -2 : 0;
2677: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2678: orntNew[1] = ornt[3] < 0 ? -2 : 0;
2679: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
2680: orntNew[2] = ornt[0] < 0 ? -2 : 0;
2681: DMPlexSetCone(rdm, newp, coneNew);
2682: DMPlexSetConeOrientation(rdm, newp, orntNew);
2683: #if 1
2684: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2685: for (p = 0; p < 3; ++p) {
2686: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2687: }
2688: #endif
2689: supportNew[0] = (c - cStart)*8 + 2;
2690: supportNew[1] = (c - cStart)*8 + 2+4;
2691: DMPlexSetSupport(rdm, newp, supportNew);
2692: #if 1
2693: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2694: for (p = 0; p < 2; ++p) {
2695: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
2696: }
2697: #endif
2698: ++newp;
2699: /* Face D: {d, e, f} */
2700: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
2701: orntNew[0] = ornt[1] < 0 ? -2 : 0;
2702: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2703: orntNew[1] = ornt[3] < 0 ? -2 : 0;
2704: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2705: orntNew[2] = ornt[2] < 0 ? -2 : 0;
2706: DMPlexSetCone(rdm, newp, coneNew);
2707: DMPlexSetConeOrientation(rdm, newp, orntNew);
2708: #if 1
2709: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2710: for (p = 0; p < 3; ++p) {
2711: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2712: }
2713: #endif
2714: supportNew[0] = (c - cStart)*8 + 3;
2715: supportNew[1] = (c - cStart)*8 + 3+4;
2716: DMPlexSetSupport(rdm, newp, supportNew);
2717: #if 1
2718: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2719: for (p = 0; p < 2; ++p) {
2720: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
2721: }
2722: #endif
2723: ++newp;
2724: /* Face E: {d, f, a} */
2725: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2726: orntNew[0] = ornt[2] < 0 ? 0 : -2;
2727: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
2728: orntNew[1] = -2;
2729: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2730: orntNew[2] = ornt[1] < 0 ? -2 : 0;
2731: DMPlexSetCone(rdm, newp, coneNew);
2732: DMPlexSetConeOrientation(rdm, newp, orntNew);
2733: #if 1
2734: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2735: for (p = 0; p < 3; ++p) {
2736: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2737: }
2738: #endif
2739: supportNew[0] = (c - cStart)*8 + 0+4;
2740: supportNew[1] = (c - cStart)*8 + 3+4;
2741: DMPlexSetSupport(rdm, newp, supportNew);
2742: #if 1
2743: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2744: for (p = 0; p < 2; ++p) {
2745: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
2746: }
2747: #endif
2748: ++newp;
2749: /* Face F: {c, a, f} */
2750: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2751: orntNew[0] = ornt[0] < 0 ? -2 : 0;
2752: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
2753: orntNew[1] = 0;
2754: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
2755: orntNew[2] = ornt[2] < 0 ? 0 : -2;
2756: DMPlexSetCone(rdm, newp, coneNew);
2757: DMPlexSetConeOrientation(rdm, newp, orntNew);
2758: #if 1
2759: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2760: for (p = 0; p < 3; ++p) {
2761: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2762: }
2763: #endif
2764: supportNew[0] = (c - cStart)*8 + 0+4;
2765: supportNew[1] = (c - cStart)*8 + 2+4;
2766: DMPlexSetSupport(rdm, newp, supportNew);
2767: #if 1
2768: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2769: for (p = 0; p < 2; ++p) {
2770: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
2771: }
2772: #endif
2773: ++newp;
2774: /* Face G: {e, a, f} */
2775: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2776: orntNew[0] = ornt[1] < 0 ? -2 : 0;
2777: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
2778: orntNew[1] = 0;
2779: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2780: orntNew[2] = ornt[3] < 0 ? 0 : -2;
2781: DMPlexSetCone(rdm, newp, coneNew);
2782: DMPlexSetConeOrientation(rdm, newp, orntNew);
2783: #if 1
2784: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2785: for (p = 0; p < 3; ++p) {
2786: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2787: }
2788: #endif
2789: supportNew[0] = (c - cStart)*8 + 1+4;
2790: supportNew[1] = (c - cStart)*8 + 3+4;
2791: DMPlexSetSupport(rdm, newp, supportNew);
2792: #if 1
2793: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2794: for (p = 0; p < 2; ++p) {
2795: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
2796: }
2797: #endif
2798: ++newp;
2799: /* Face H: {a, b, f} */
2800: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2801: orntNew[0] = ornt[0] < 0 ? -2 : 0;
2802: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2803: orntNew[1] = ornt[3] < 0 ? 0 : -2;
2804: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
2805: orntNew[2] = -2;
2806: DMPlexSetCone(rdm, newp, coneNew);
2807: DMPlexSetConeOrientation(rdm, newp, orntNew);
2808: #if 1
2809: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2810: for (p = 0; p < 3; ++p) {
2811: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2812: }
2813: #endif
2814: supportNew[0] = (c - cStart)*8 + 1+4;
2815: supportNew[1] = (c - cStart)*8 + 2+4;
2816: DMPlexSetSupport(rdm, newp, supportNew);
2817: #if 1
2818: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
2819: for (p = 0; p < 2; ++p) {
2820: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
2821: }
2822: #endif
2823: ++newp;
2824: }
2825: /* Hybrid split faces have 4 edges and same cells */
2826: for (f = fMax; f < fEnd; ++f) {
2827: const PetscInt *cone, *ornt, *support;
2828: PetscInt coneNew[4], orntNew[4];
2829: PetscInt supportNew[2], size, s, c;
2831: DMPlexGetCone(dm, f, &cone);
2832: DMPlexGetConeOrientation(dm, f, &ornt);
2833: DMPlexGetSupportSize(dm, f, &size);
2834: DMPlexGetSupport(dm, f, &support);
2835: for (r = 0; r < 2; ++r) {
2836: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
2838: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
2839: orntNew[0] = ornt[0];
2840: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
2841: orntNew[1] = ornt[1];
2842: coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
2843: orntNew[2+r] = 0;
2844: coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
2845: orntNew[3-r] = 0;
2846: DMPlexSetCone(rdm, newp, coneNew);
2847: DMPlexSetConeOrientation(rdm, newp, orntNew);
2848: #if 1
2849: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
2850: for (p = 0; p < 2; ++p) {
2851: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2852: }
2853: for (p = 2; p < 4; ++p) {
2854: if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
2855: }
2856: #endif
2857: for (s = 0; s < size; ++s) {
2858: const PetscInt *coneCell, *orntCell, *fornt;
2860: DMPlexGetCone(dm, support[s], &coneCell);
2861: DMPlexGetConeOrientation(dm, support[s], &orntCell);
2862: for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
2863: if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]);
2864: DMPlexGetConeOrientation(dm, coneCell[0], &fornt);
2865: supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%3;
2866: }
2867: DMPlexSetSupport(rdm, newp, supportNew);
2868: #if 1
2869: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
2870: for (p = 0; p < size; ++p) {
2871: if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
2872: }
2873: #endif
2874: }
2875: }
2876: /* Hybrid cell faces have 4 edges and 2 cells */
2877: for (c = cMax; c < cEnd; ++c) {
2878: PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
2879: const PetscInt *cone, *ornt;
2880: PetscInt coneNew[4], orntNew[4];
2881: PetscInt supportNew[2];
2883: DMPlexGetCone(dm, c, &cone);
2884: DMPlexGetConeOrientation(dm, c, &ornt);
2885: for (r = 0; r < 3; ++r) {
2886: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3);
2887: orntNew[0] = 0;
2888: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3);
2889: orntNew[1] = 0;
2890: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax);
2891: orntNew[2] = 0;
2892: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)] - fMax);
2893: orntNew[3] = 0;
2894: DMPlexSetCone(rdm, newp+r, coneNew);
2895: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
2896: #if 1
2897: if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
2898: for (p = 0; p < 2; ++p) {
2899: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
2900: }
2901: for (p = 2; p < 4; ++p) {
2902: if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
2903: }
2904: #endif
2905: supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
2906: supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
2907: DMPlexSetSupport(rdm, newp+r, supportNew);
2908: #if 1
2909: if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
2910: for (p = 0; p < 2; ++p) {
2911: if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
2912: }
2913: #endif
2914: }
2915: }
2916: /* Interior split edges have 2 vertices and the same faces as the parent */
2917: for (e = eStart; e < eMax; ++e) {
2918: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2920: for (r = 0; r < 2; ++r) {
2921: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
2922: const PetscInt *cone, *ornt, *support;
2923: PetscInt coneNew[2], coneSize, c, supportSize, s;
2925: DMPlexGetCone(dm, e, &cone);
2926: coneNew[0] = vStartNew + (cone[0] - vStart);
2927: coneNew[1] = vStartNew + (cone[1] - vStart);
2928: coneNew[(r+1)%2] = newv;
2929: DMPlexSetCone(rdm, newp, coneNew);
2930: #if 1
2931: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
2932: for (p = 0; p < 2; ++p) {
2933: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2934: }
2935: #endif
2936: DMPlexGetSupportSize(dm, e, &supportSize);
2937: DMPlexGetSupport(dm, e, &support);
2938: for (s = 0; s < supportSize; ++s) {
2939: DMPlexGetConeSize(dm, support[s], &coneSize);
2940: DMPlexGetCone(dm, support[s], &cone);
2941: DMPlexGetConeOrientation(dm, support[s], &ornt);
2942: for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
2943: if (support[s] < fMax) {
2944: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2945: } else {
2946: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
2947: }
2948: }
2949: DMPlexSetSupport(rdm, newp, supportRef);
2950: #if 1
2951: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
2952: for (p = 0; p < supportSize; ++p) {
2953: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid face [%d, %d)", supportRef[p], fStartNew, fEndNew);
2954: }
2955: #endif
2956: }
2957: }
2958: /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
2959: for (f = fStart; f < fMax; ++f) {
2960: const PetscInt *cone, *ornt, *support;
2961: PetscInt coneSize, supportSize, s;
2963: DMPlexGetSupportSize(dm, f, &supportSize);
2964: DMPlexGetSupport(dm, f, &support);
2965: for (r = 0; r < 3; ++r) {
2966: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
2967: PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2968: PetscInt fint[24] = { 1, 7, -1, -1, 0, 5,
2969: -1, -1, 1, 6, 0, 4,
2970: 2, 5, 3, 4, -1, -1,
2971: -1, -1, 3, 6, 2, 7};
2973: DMPlexGetCone(dm, f, &cone);
2974: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2975: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2976: DMPlexSetCone(rdm, newp, coneNew);
2977: #if 1
2978: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
2979: for (p = 0; p < 2; ++p) {
2980: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2981: }
2982: #endif
2983: supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2984: supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2985: for (s = 0; s < supportSize; ++s) {
2986: DMPlexGetConeSize(dm, support[s], &coneSize);
2987: DMPlexGetCone(dm, support[s], &cone);
2988: DMPlexGetConeOrientation(dm, support[s], &ornt);
2989: for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
2990: if (support[s] < cMax) {
2991: /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
2992: er = GetTetSomethingInverse_Static(ornt[c], r);
2993: if (er == eint[c]) {
2994: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2995: } else {
2996: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2997: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2998: }
2999: } else {
3000: supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(ornt[c], r) + 1)%3;
3001: }
3002: }
3003: DMPlexSetSupport(rdm, newp, supportRef);
3004: #if 1
3005: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
3006: for (p = 0; p < intFaces; ++p) {
3007: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid face [%d, %d)", supportRef[p], fStartNew, fEndNew);
3008: }
3009: #endif
3010: }
3011: }
3012: /* Interior cell edges have 2 vertices and 4 faces */
3013: for (c = cStart; c < cMax; ++c) {
3014: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
3015: const PetscInt *cone, *ornt, *fcone;
3016: PetscInt coneNew[2], supportNew[4], find;
3018: DMPlexGetCone(dm, c, &cone);
3019: DMPlexGetConeOrientation(dm, c, &ornt);
3020: DMPlexGetCone(dm, cone[0], &fcone);
3021: find = GetTriEdge_Static(ornt[0], 0);
3022: coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3023: DMPlexGetCone(dm, cone[2], &fcone);
3024: find = GetTriEdge_Static(ornt[2], 1);
3025: coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3026: DMPlexSetCone(rdm, newp, coneNew);
3027: #if 1
3028: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
3029: for (p = 0; p < 2; ++p) {
3030: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
3031: }
3032: #endif
3033: supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
3034: supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
3035: supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
3036: supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
3037: DMPlexSetSupport(rdm, newp, supportNew);
3038: #if 1
3039: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
3040: for (p = 0; p < 4; ++p) {
3041: if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fMaxNew);
3042: }
3043: #endif
3044: }
3045: /* Hybrid edges have two vertices and the same faces */
3046: for (e = eMax; e < eEnd; ++e) {
3047: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
3048: const PetscInt *cone, *support, *fcone;
3049: PetscInt coneNew[2], size, fsize, s;
3051: DMPlexGetCone(dm, e, &cone);
3052: DMPlexGetSupportSize(dm, e, &size);
3053: DMPlexGetSupport(dm, e, &support);
3054: coneNew[0] = vStartNew + (cone[0] - vStart);
3055: coneNew[1] = vStartNew + (cone[1] - vStart);
3056: DMPlexSetCone(rdm, newp, coneNew);
3057: #if 1
3058: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
3059: for (p = 0; p < 2; ++p) {
3060: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
3061: }
3062: #endif
3063: for (s = 0; s < size; ++s) {
3064: DMPlexGetConeSize(dm, support[s], &fsize);
3065: DMPlexGetCone(dm, support[s], &fcone);
3066: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
3067: if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]);
3068: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
3069: }
3070: DMPlexSetSupport(rdm, newp, supportRef);
3071: #if 1
3072: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
3073: for (p = 0; p < size; ++p) {
3074: if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
3075: }
3076: #endif
3077: }
3078: /* Hybrid face edges have 2 vertices and 2+2*cells faces */
3079: for (f = fMax; f < fEnd; ++f) {
3080: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
3081: const PetscInt *cone, *support, *ccone, *cornt;
3082: PetscInt coneNew[2], size, csize, s;
3084: DMPlexGetCone(dm, f, &cone);
3085: DMPlexGetSupportSize(dm, f, &size);
3086: DMPlexGetSupport(dm, f, &support);
3087: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
3088: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
3089: DMPlexSetCone(rdm, newp, coneNew);
3090: #if 1
3091: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
3092: for (p = 0; p < 2; ++p) {
3093: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
3094: }
3095: #endif
3096: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
3097: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
3098: for (s = 0; s < size; ++s) {
3099: DMPlexGetConeSize(dm, support[s], &csize);
3100: DMPlexGetCone(dm, support[s], &ccone);
3101: DMPlexGetConeOrientation(dm, support[s], &cornt);
3102: for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
3103: if ((c < 2) || (c >= csize)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Hybrid face %d is not in cone of hybrid cell %d", f, support[s]);
3104: supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + GetTriSubfaceInverse_Static(cornt[0], c-2);
3105: supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(cornt[0], c-2) + 1)%3;
3106: }
3107: DMPlexSetSupport(rdm, newp, supportRef);
3108: #if 1
3109: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
3110: for (p = 0; p < 2+size*2; ++p) {
3111: if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
3112: }
3113: #endif
3114: }
3115: /* Interior vertices have identical supports */
3116: for (v = vStart; v < vEnd; ++v) {
3117: const PetscInt newp = vStartNew + (v - vStart);
3118: const PetscInt *support, *cone;
3119: PetscInt size, s;
3121: DMPlexGetSupportSize(dm, v, &size);
3122: DMPlexGetSupport(dm, v, &support);
3123: for (s = 0; s < size; ++s) {
3124: PetscInt r = 0;
3126: DMPlexGetCone(dm, support[s], &cone);
3127: if (cone[1] == v) r = 1;
3128: if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
3129: else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
3130: }
3131: DMPlexSetSupport(rdm, newp, supportRef);
3132: #if 1
3133: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
3134: for (p = 0; p < size; ++p) {
3135: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
3136: }
3137: #endif
3138: }
3139: /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
3140: for (e = eStart; e < eMax; ++e) {
3141: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
3142: const PetscInt *cone, *support;
3143: PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
3145: DMPlexGetSupportSize(dm, e, &size);
3146: DMPlexGetSupport(dm, e, &support);
3147: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
3148: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
3149: for (s = 0; s < size; ++s) {
3150: PetscInt r = 0;
3152: if (support[s] < fMax) {
3153: DMPlexGetConeSize(dm, support[s], &coneSize);
3154: DMPlexGetCone(dm, support[s], &cone);
3155: for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
3156: supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
3157: supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
3158: faceSize += 2;
3159: } else {
3160: supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
3161: ++faceSize;
3162: }
3163: }
3164: DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
3165: for (s = 0; s < starSize*2; s += 2) {
3166: const PetscInt *cone, *ornt;
3167: PetscInt e01, e23;
3169: if ((star[s] >= cStart) && (star[s] < cMax)) {
3170: /* Check edge 0-1 */
3171: DMPlexGetCone(dm, star[s], &cone);
3172: DMPlexGetConeOrientation(dm, star[s], &ornt);
3173: DMPlexGetCone(dm, cone[0], &cone);
3174: e01 = cone[GetTriEdge_Static(ornt[0], 0)];
3175: /* Check edge 2-3 */
3176: DMPlexGetCone(dm, star[s], &cone);
3177: DMPlexGetConeOrientation(dm, star[s], &ornt);
3178: DMPlexGetCone(dm, cone[2], &cone);
3179: e23 = cone[GetTriEdge_Static(ornt[2], 1)];
3180: if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
3181: }
3182: }
3183: DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);
3184: DMPlexSetSupport(rdm, newp, supportRef);
3185: #if 1
3186: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
3187: for (p = 0; p < 2+faceSize+cellSize; ++p) {
3188: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
3189: }
3190: #endif
3191: }
3192: PetscFree(supportRef);
3193: DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);
3194: break;
3195: case 6:
3196: /* Hex 3D */
3197: /*
3198: Bottom (viewed from top) Top
3199: 1---------2---------2 7---------2---------6
3200: | | | | | |
3201: | B 2 C | | H 2 G |
3202: | | | | | |
3203: 3----3----0----1----1 3----3----0----1----1
3204: | | | | | |
3205: | A 0 D | | E 0 F |
3206: | | | | | |
3207: 0---------0---------3 4---------0---------5
3208: */
3209: /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
3210: for (c = cStart; c < cEnd; ++c) {
3211: const PetscInt newp = (c - cStart)*8;
3212: const PetscInt *cone, *ornt;
3213: PetscInt coneNew[6], orntNew[6];
3215: DMPlexGetCone(dm, c, &cone);
3216: DMPlexGetConeOrientation(dm, c, &ornt);
3217: /* A hex */
3218: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
3219: orntNew[0] = ornt[0];
3220: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */
3221: orntNew[1] = 0;
3222: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
3223: orntNew[2] = ornt[2];
3224: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */
3225: orntNew[3] = 0;
3226: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */
3227: orntNew[4] = 0;
3228: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
3229: orntNew[5] = ornt[5];
3230: DMPlexSetCone(rdm, newp+0, coneNew);
3231: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3232: #if 1
3233: if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
3234: for (p = 0; p < 6; ++p) {
3235: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
3236: }
3237: #endif
3238: /* B hex */
3239: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
3240: orntNew[0] = ornt[0];
3241: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3242: orntNew[1] = 0;
3243: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */
3244: orntNew[2] = -1;
3245: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
3246: orntNew[3] = ornt[3];
3247: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */
3248: orntNew[4] = 0;
3249: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
3250: orntNew[5] = ornt[5];
3251: DMPlexSetCone(rdm, newp+1, coneNew);
3252: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3253: #if 1
3254: if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
3255: for (p = 0; p < 6; ++p) {
3256: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
3257: }
3258: #endif
3259: /* C hex */
3260: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
3261: orntNew[0] = ornt[0];
3262: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3263: orntNew[1] = 0;
3264: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */
3265: orntNew[2] = -1;
3266: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
3267: orntNew[3] = ornt[3];
3268: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
3269: orntNew[4] = ornt[4];
3270: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */
3271: orntNew[5] = -4;
3272: DMPlexSetCone(rdm, newp+2, coneNew);
3273: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3274: #if 1
3275: if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
3276: for (p = 0; p < 6; ++p) {
3277: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
3278: }
3279: #endif
3280: /* D hex */
3281: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
3282: orntNew[0] = ornt[0];
3283: coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */
3284: orntNew[1] = 0;
3285: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
3286: orntNew[2] = ornt[2];
3287: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */
3288: orntNew[3] = 0;
3289: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
3290: orntNew[4] = ornt[4];
3291: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */
3292: orntNew[5] = -4;
3293: DMPlexSetCone(rdm, newp+3, coneNew);
3294: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3295: #if 1
3296: if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
3297: for (p = 0; p < 6; ++p) {
3298: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
3299: }
3300: #endif
3301: /* E hex */
3302: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */
3303: orntNew[0] = -4;
3304: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
3305: orntNew[1] = ornt[1];
3306: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
3307: orntNew[2] = ornt[2];
3308: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */
3309: orntNew[3] = 0;
3310: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */
3311: orntNew[4] = -1;
3312: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
3313: orntNew[5] = ornt[5];
3314: DMPlexSetCone(rdm, newp+4, coneNew);
3315: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
3316: #if 1
3317: if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew);
3318: for (p = 0; p < 6; ++p) {
3319: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
3320: }
3321: #endif
3322: /* F hex */
3323: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */
3324: orntNew[0] = -4;
3325: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
3326: orntNew[1] = ornt[1];
3327: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
3328: orntNew[2] = ornt[2];
3329: coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */
3330: orntNew[3] = -1;
3331: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
3332: orntNew[4] = ornt[4];
3333: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */
3334: orntNew[5] = 1;
3335: DMPlexSetCone(rdm, newp+5, coneNew);
3336: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
3337: #if 1
3338: if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew);
3339: for (p = 0; p < 6; ++p) {
3340: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
3341: }
3342: #endif
3343: /* G hex */
3344: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3345: orntNew[0] = -4;
3346: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
3347: orntNew[1] = ornt[1];
3348: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */
3349: orntNew[2] = 0;
3350: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
3351: orntNew[3] = ornt[3];
3352: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
3353: orntNew[4] = ornt[4];
3354: coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */
3355: orntNew[5] = -3;
3356: DMPlexSetCone(rdm, newp+6, coneNew);
3357: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
3358: #if 1
3359: if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew);
3360: for (p = 0; p < 6; ++p) {
3361: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
3362: }
3363: #endif
3364: /* H hex */
3365: coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3366: orntNew[0] = -4;
3367: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
3368: orntNew[1] = ornt[1];
3369: coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */
3370: orntNew[2] = -1;
3371: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
3372: orntNew[3] = ornt[3];
3373: coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */
3374: orntNew[4] = 3;
3375: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
3376: orntNew[5] = ornt[5];
3377: DMPlexSetCone(rdm, newp+7, coneNew);
3378: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
3379: #if 1
3380: if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew);
3381: for (p = 0; p < 6; ++p) {
3382: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
3383: }
3384: #endif
3385: }
3386: /* Split faces have 4 edges and the same cells as the parent */
3387: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
3388: PetscMalloc1((4 + maxSupportSize*2), &supportRef);
3389: for (f = fStart; f < fEnd; ++f) {
3390: for (r = 0; r < 4; ++r) {
3391: /* TODO: This can come from GetFaces_Internal() */
3392: 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};
3393: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
3394: const PetscInt *cone, *ornt, *support;
3395: PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s;
3397: DMPlexGetCone(dm, f, &cone);
3398: DMPlexGetConeOrientation(dm, f, &ornt);
3399: coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3400: orntNew[(r+3)%4] = ornt[(r+3)%4];
3401: coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3402: orntNew[(r+0)%4] = ornt[r];
3403: coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3404: orntNew[(r+1)%4] = 0;
3405: coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3406: orntNew[(r+2)%4] = -2;
3407: DMPlexSetCone(rdm, newp, coneNew);
3408: DMPlexSetConeOrientation(rdm, newp, orntNew);
3409: #if 1
3410: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3411: for (p = 0; p < 4; ++p) {
3412: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3413: }
3414: #endif
3415: DMPlexGetSupportSize(dm, f, &supportSize);
3416: DMPlexGetSupport(dm, f, &support);
3417: for (s = 0; s < supportSize; ++s) {
3418: DMPlexGetConeSize(dm, support[s], &coneSize);
3419: DMPlexGetCone(dm, support[s], &cone);
3420: DMPlexGetConeOrientation(dm, support[s], &ornt);
3421: for (c = 0; c < coneSize; ++c) {
3422: if (cone[c] == f) break;
3423: }
3424: supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
3425: }
3426: DMPlexSetSupport(rdm, newp, supportRef);
3427: #if 1
3428: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3429: for (p = 0; p < supportSize; ++p) {
3430: if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
3431: }
3432: #endif
3433: }
3434: }
3435: /* Interior faces have 4 edges and 2 cells */
3436: for (c = cStart; c < cEnd; ++c) {
3437: 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};
3438: const PetscInt *cone, *ornt;
3439: PetscInt newp, coneNew[4], orntNew[4], supportNew[2];
3441: DMPlexGetCone(dm, c, &cone);
3442: DMPlexGetConeOrientation(dm, c, &ornt);
3443: /* A-D face */
3444: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
3445: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
3446: orntNew[0] = 0;
3447: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
3448: orntNew[1] = 0;
3449: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
3450: orntNew[2] = -2;
3451: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
3452: orntNew[3] = -2;
3453: DMPlexSetCone(rdm, newp, coneNew);
3454: DMPlexSetConeOrientation(rdm, newp, orntNew);
3455: #if 1
3456: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3457: for (p = 0; p < 4; ++p) {
3458: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3459: }
3460: #endif
3461: /* C-D face */
3462: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
3463: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
3464: orntNew[0] = 0;
3465: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
3466: orntNew[1] = 0;
3467: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
3468: orntNew[2] = -2;
3469: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
3470: orntNew[3] = -2;
3471: DMPlexSetCone(rdm, newp, coneNew);
3472: DMPlexSetConeOrientation(rdm, newp, orntNew);
3473: #if 1
3474: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3475: for (p = 0; p < 4; ++p) {
3476: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3477: }
3478: #endif
3479: /* B-C face */
3480: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
3481: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
3482: orntNew[0] = -2;
3483: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
3484: orntNew[1] = 0;
3485: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
3486: orntNew[2] = 0;
3487: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
3488: orntNew[3] = -2;
3489: DMPlexSetCone(rdm, newp, coneNew);
3490: DMPlexSetConeOrientation(rdm, newp, orntNew);
3491: #if 1
3492: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3493: for (p = 0; p < 4; ++p) {
3494: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3495: }
3496: #endif
3497: /* A-B face */
3498: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
3499: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
3500: orntNew[0] = -2;
3501: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
3502: orntNew[1] = 0;
3503: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
3504: orntNew[2] = 0;
3505: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0;
3506: orntNew[3] = -2;
3507: DMPlexSetCone(rdm, newp, coneNew);
3508: DMPlexSetConeOrientation(rdm, newp, orntNew);
3509: #if 1
3510: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3511: for (p = 0; p < 4; ++p) {
3512: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3513: }
3514: #endif
3515: /* E-F face */
3516: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
3517: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
3518: orntNew[0] = -2;
3519: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
3520: orntNew[1] = -2;
3521: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
3522: orntNew[2] = 0;
3523: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
3524: orntNew[3] = 0;
3525: DMPlexSetCone(rdm, newp, coneNew);
3526: DMPlexSetConeOrientation(rdm, newp, orntNew);
3527: #if 1
3528: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3529: for (p = 0; p < 4; ++p) {
3530: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3531: }
3532: #endif
3533: /* F-G face */
3534: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
3535: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
3536: orntNew[0] = -2;
3537: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
3538: orntNew[1] = -2;
3539: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
3540: orntNew[2] = 0;
3541: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
3542: orntNew[3] = 0;
3543: DMPlexSetCone(rdm, newp, coneNew);
3544: DMPlexSetConeOrientation(rdm, newp, orntNew);
3545: #if 1
3546: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3547: for (p = 0; p < 4; ++p) {
3548: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3549: }
3550: #endif
3551: /* G-H face */
3552: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
3553: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
3554: orntNew[0] = -2;
3555: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
3556: orntNew[1] = 0;
3557: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
3558: orntNew[2] = 0;
3559: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
3560: orntNew[3] = -2;
3561: DMPlexSetCone(rdm, newp, coneNew);
3562: DMPlexSetConeOrientation(rdm, newp, orntNew);
3563: #if 1
3564: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3565: for (p = 0; p < 4; ++p) {
3566: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3567: }
3568: #endif
3569: /* E-H face */
3570: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
3571: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
3572: orntNew[0] = -2;
3573: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
3574: orntNew[1] = -2;
3575: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
3576: orntNew[2] = 0;
3577: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1;
3578: orntNew[3] = 0;
3579: DMPlexSetCone(rdm, newp, coneNew);
3580: DMPlexSetConeOrientation(rdm, newp, orntNew);
3581: #if 1
3582: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3583: for (p = 0; p < 4; ++p) {
3584: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3585: }
3586: #endif
3587: /* A-E face */
3588: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
3589: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
3590: orntNew[0] = 0;
3591: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
3592: orntNew[1] = 0;
3593: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
3594: orntNew[2] = -2;
3595: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
3596: orntNew[3] = -2;
3597: DMPlexSetCone(rdm, newp, coneNew);
3598: DMPlexSetConeOrientation(rdm, newp, orntNew);
3599: #if 1
3600: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3601: for (p = 0; p < 4; ++p) {
3602: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3603: }
3604: #endif
3605: /* D-F face */
3606: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
3607: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
3608: orntNew[0] = -2;
3609: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
3610: orntNew[1] = 0;
3611: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
3612: orntNew[2] = 0;
3613: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2;
3614: orntNew[3] = -2;
3615: DMPlexSetCone(rdm, newp, coneNew);
3616: DMPlexSetConeOrientation(rdm, newp, orntNew);
3617: #if 1
3618: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3619: for (p = 0; p < 4; ++p) {
3620: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3621: }
3622: #endif
3623: /* C-G face */
3624: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
3625: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4;
3626: orntNew[0] = -2;
3627: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
3628: orntNew[1] = -2;
3629: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
3630: orntNew[2] = 0;
3631: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
3632: orntNew[3] = 0;
3633: DMPlexSetCone(rdm, newp, coneNew);
3634: DMPlexSetConeOrientation(rdm, newp, orntNew);
3635: #if 1
3636: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3637: for (p = 0; p < 4; ++p) {
3638: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3639: }
3640: #endif
3641: /* B-H face */
3642: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
3643: coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5;
3644: orntNew[0] = 0;
3645: coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3;
3646: orntNew[1] = -2;
3647: coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
3648: orntNew[2] = -2;
3649: coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
3650: orntNew[3] = 0;
3651: DMPlexSetCone(rdm, newp, coneNew);
3652: DMPlexSetConeOrientation(rdm, newp, orntNew);
3653: #if 1
3654: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3655: for (p = 0; p < 4; ++p) {
3656: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3657: }
3658: #endif
3659: for (r = 0; r < 12; ++r) {
3660: newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
3661: supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
3662: supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
3663: DMPlexSetSupport(rdm, newp, supportNew);
3664: #if 1
3665: if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3666: for (p = 0; p < 2; ++p) {
3667: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
3668: }
3669: #endif
3670: }
3671: }
3672: /* Split edges have 2 vertices and the same faces as the parent */
3673: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
3674: for (e = eStart; e < eEnd; ++e) {
3675: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
3677: for (r = 0; r < 2; ++r) {
3678: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
3679: const PetscInt *cone, *ornt, *support;
3680: PetscInt coneNew[2], coneSize, c, supportSize, s;
3682: DMPlexGetCone(dm, e, &cone);
3683: coneNew[0] = vStartNew + (cone[0] - vStart);
3684: coneNew[1] = vStartNew + (cone[1] - vStart);
3685: coneNew[(r+1)%2] = newv;
3686: DMPlexSetCone(rdm, newp, coneNew);
3687: #if 1
3688: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3689: for (p = 0; p < 2; ++p) {
3690: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
3691: }
3692: #endif
3693: DMPlexGetSupportSize(dm, e, &supportSize);
3694: DMPlexGetSupport(dm, e, &support);
3695: for (s = 0; s < supportSize; ++s) {
3696: DMPlexGetConeSize(dm, support[s], &coneSize);
3697: DMPlexGetCone(dm, support[s], &cone);
3698: DMPlexGetConeOrientation(dm, support[s], &ornt);
3699: for (c = 0; c < coneSize; ++c) {
3700: if (cone[c] == e) break;
3701: }
3702: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
3703: }
3704: DMPlexSetSupport(rdm, newp, supportRef);
3705: #if 1
3706: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3707: for (p = 0; p < supportSize; ++p) {
3708: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
3709: }
3710: #endif
3711: }
3712: }
3713: /* Face edges have 2 vertices and 2+cells faces */
3714: for (f = fStart; f < fEnd; ++f) {
3715: 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};
3716: const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
3717: const PetscInt *cone, *coneCell, *orntCell, *support;
3718: PetscInt coneNew[2], coneSize, c, supportSize, s;
3720: DMPlexGetCone(dm, f, &cone);
3721: for (r = 0; r < 4; ++r) {
3722: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3724: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
3725: coneNew[1] = newv;
3726: DMPlexSetCone(rdm, newp, coneNew);
3727: #if 1
3728: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3729: for (p = 0; p < 2; ++p) {
3730: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
3731: }
3732: #endif
3733: DMPlexGetSupportSize(dm, f, &supportSize);
3734: DMPlexGetSupport(dm, f, &support);
3735: supportRef[0] = fStartNew + (f - fStart)*4 + r;
3736: supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
3737: for (s = 0; s < supportSize; ++s) {
3738: DMPlexGetConeSize(dm, support[s], &coneSize);
3739: DMPlexGetCone(dm, support[s], &coneCell);
3740: DMPlexGetConeOrientation(dm, support[s], &orntCell);
3741: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
3742: supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
3743: }
3744: DMPlexSetSupport(rdm, newp, supportRef);
3745: #if 1
3746: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3747: for (p = 0; p < 2+supportSize; ++p) {
3748: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
3749: }
3750: #endif
3751: }
3752: }
3753: /* Cell edges have 2 vertices and 4 faces */
3754: for (c = cStart; c < cEnd; ++c) {
3755: 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};
3756: const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
3757: const PetscInt *cone;
3758: PetscInt coneNew[2], supportNew[4];
3760: DMPlexGetCone(dm, c, &cone);
3761: for (r = 0; r < 6; ++r) {
3762: const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
3764: coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
3765: coneNew[1] = newv;
3766: DMPlexSetCone(rdm, newp, coneNew);
3767: #if 1
3768: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3769: for (p = 0; p < 2; ++p) {
3770: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
3771: }
3772: #endif
3773: for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
3774: DMPlexSetSupport(rdm, newp, supportNew);
3775: #if 1
3776: if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3777: for (p = 0; p < 4; ++p) {
3778: if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew);
3779: }
3780: #endif
3781: }
3782: }
3783: /* Old vertices have identical supports */
3784: for (v = vStart; v < vEnd; ++v) {
3785: const PetscInt newp = vStartNew + (v - vStart);
3786: const PetscInt *support, *cone;
3787: PetscInt size, s;
3789: DMPlexGetSupportSize(dm, v, &size);
3790: DMPlexGetSupport(dm, v, &support);
3791: for (s = 0; s < size; ++s) {
3792: PetscInt r = 0;
3794: DMPlexGetCone(dm, support[s], &cone);
3795: if (cone[1] == v) r = 1;
3796: supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
3797: }
3798: DMPlexSetSupport(rdm, newp, supportRef);
3799: #if 1
3800: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
3801: for (p = 0; p < size; ++p) {
3802: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
3803: }
3804: #endif
3805: }
3806: /* Edge vertices have 2 + faces supports */
3807: for (e = eStart; e < eEnd; ++e) {
3808: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
3809: const PetscInt *cone, *support;
3810: PetscInt size, s;
3812: DMPlexGetSupportSize(dm, e, &size);
3813: DMPlexGetSupport(dm, e, &support);
3814: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
3815: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
3816: for (s = 0; s < size; ++s) {
3817: PetscInt r;
3819: DMPlexGetCone(dm, support[s], &cone);
3820: for (r = 0; r < 4; ++r) if (cone[r] == e) break;
3821: supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
3822: }
3823: DMPlexSetSupport(rdm, newp, supportRef);
3824: #if 1
3825: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
3826: for (p = 0; p < 2+size; ++p) {
3827: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
3828: }
3829: #endif
3830: }
3831: /* Face vertices have 4 + cells supports */
3832: for (f = fStart; f < fEnd; ++f) {
3833: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
3834: const PetscInt *cone, *support;
3835: PetscInt size, s;
3837: DMPlexGetSupportSize(dm, f, &size);
3838: DMPlexGetSupport(dm, f, &support);
3839: for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3840: for (s = 0; s < size; ++s) {
3841: PetscInt r;
3843: DMPlexGetCone(dm, support[s], &cone);
3844: for (r = 0; r < 6; ++r) if (cone[r] == f) break;
3845: supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
3846: }
3847: DMPlexSetSupport(rdm, newp, supportRef);
3848: #if 1
3849: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
3850: for (p = 0; p < 4+size; ++p) {
3851: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
3852: }
3853: #endif
3854: }
3855: /* Cell vertices have 6 supports */
3856: for (c = cStart; c < cEnd; ++c) {
3857: const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
3858: PetscInt supportNew[6];
3860: for (r = 0; r < 6; ++r) {
3861: supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
3862: }
3863: DMPlexSetSupport(rdm, newp, supportNew);
3864: }
3865: PetscFree(supportRef);
3866: break;
3867: case 8:
3868: /* Hybrid Hex 3D */
3869: DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);
3870: /*
3871: Bottom (viewed from top) Top
3872: 1---------2---------2 7---------2---------6
3873: | | | | | |
3874: | B 2 C | | H 2 G |
3875: | | | | | |
3876: 3----3----0----1----1 3----3----0----1----1
3877: | | | | | |
3878: | A 0 D | | E 0 F |
3879: | | | | | |
3880: 0---------0---------3 4---------0---------5
3881: */
3882: /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
3883: for (c = cStart; c < cMax; ++c) {
3884: const PetscInt newp = (c - cStart)*8;
3885: const PetscInt *cone, *ornt;
3886: PetscInt coneNew[6], orntNew[6];
3888: DMPlexGetCone(dm, c, &cone);
3889: DMPlexGetConeOrientation(dm, c, &ornt);
3890: /* A hex */
3891: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
3892: orntNew[0] = ornt[0];
3893: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */
3894: orntNew[1] = 0;
3895: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
3896: orntNew[2] = ornt[2];
3897: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */
3898: orntNew[3] = 0;
3899: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */
3900: orntNew[4] = 0;
3901: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
3902: orntNew[5] = ornt[5];
3903: DMPlexSetCone(rdm, newp+0, coneNew);
3904: DMPlexSetConeOrientation(rdm, newp+0, orntNew);
3905: #if 1
3906: if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cMaxNew);
3907: for (p = 0; p < 6; ++p) {
3908: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
3909: }
3910: #endif
3911: /* B hex */
3912: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
3913: orntNew[0] = ornt[0];
3914: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3915: orntNew[1] = 0;
3916: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */
3917: orntNew[2] = -1;
3918: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
3919: orntNew[3] = ornt[3];
3920: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */
3921: orntNew[4] = 0;
3922: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
3923: orntNew[5] = ornt[5];
3924: DMPlexSetCone(rdm, newp+1, coneNew);
3925: DMPlexSetConeOrientation(rdm, newp+1, orntNew);
3926: #if 1
3927: if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cMaxNew);
3928: for (p = 0; p < 6; ++p) {
3929: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
3930: }
3931: #endif
3932: /* C hex */
3933: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
3934: orntNew[0] = ornt[0];
3935: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3936: orntNew[1] = 0;
3937: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */
3938: orntNew[2] = -1;
3939: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
3940: orntNew[3] = ornt[3];
3941: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
3942: orntNew[4] = ornt[4];
3943: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */
3944: orntNew[5] = -4;
3945: DMPlexSetCone(rdm, newp+2, coneNew);
3946: DMPlexSetConeOrientation(rdm, newp+2, orntNew);
3947: #if 1
3948: if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cMaxNew);
3949: for (p = 0; p < 6; ++p) {
3950: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
3951: }
3952: #endif
3953: /* D hex */
3954: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
3955: orntNew[0] = ornt[0];
3956: coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */
3957: orntNew[1] = 0;
3958: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
3959: orntNew[2] = ornt[2];
3960: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */
3961: orntNew[3] = 0;
3962: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
3963: orntNew[4] = ornt[4];
3964: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */
3965: orntNew[5] = -4;
3966: DMPlexSetCone(rdm, newp+3, coneNew);
3967: DMPlexSetConeOrientation(rdm, newp+3, orntNew);
3968: #if 1
3969: if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cMaxNew);
3970: for (p = 0; p < 6; ++p) {
3971: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
3972: }
3973: #endif
3974: /* E hex */
3975: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */
3976: orntNew[0] = -4;
3977: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
3978: orntNew[1] = ornt[1];
3979: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
3980: orntNew[2] = ornt[2];
3981: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */
3982: orntNew[3] = 0;
3983: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */
3984: orntNew[4] = -1;
3985: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
3986: orntNew[5] = ornt[5];
3987: DMPlexSetCone(rdm, newp+4, coneNew);
3988: DMPlexSetConeOrientation(rdm, newp+4, orntNew);
3989: #if 1
3990: if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cMaxNew);
3991: for (p = 0; p < 6; ++p) {
3992: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
3993: }
3994: #endif
3995: /* F hex */
3996: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */
3997: orntNew[0] = -4;
3998: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
3999: orntNew[1] = ornt[1];
4000: coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
4001: orntNew[2] = ornt[2];
4002: coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */
4003: orntNew[3] = -1;
4004: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
4005: orntNew[4] = ornt[4];
4006: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */
4007: orntNew[5] = 1;
4008: DMPlexSetCone(rdm, newp+5, coneNew);
4009: DMPlexSetConeOrientation(rdm, newp+5, orntNew);
4010: #if 1
4011: if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cMaxNew);
4012: for (p = 0; p < 6; ++p) {
4013: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
4014: }
4015: #endif
4016: /* G hex */
4017: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */
4018: orntNew[0] = -4;
4019: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
4020: orntNew[1] = ornt[1];
4021: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */
4022: orntNew[2] = 0;
4023: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
4024: orntNew[3] = ornt[3];
4025: coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
4026: orntNew[4] = ornt[4];
4027: coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */
4028: orntNew[5] = -3;
4029: DMPlexSetCone(rdm, newp+6, coneNew);
4030: DMPlexSetConeOrientation(rdm, newp+6, orntNew);
4031: #if 1
4032: if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cMaxNew);
4033: for (p = 0; p < 6; ++p) {
4034: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
4035: }
4036: #endif
4037: /* H hex */
4038: coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */
4039: orntNew[0] = -4;
4040: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
4041: orntNew[1] = ornt[1];
4042: coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */
4043: orntNew[2] = -1;
4044: coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
4045: orntNew[3] = ornt[3];
4046: coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */
4047: orntNew[4] = 3;
4048: coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
4049: orntNew[5] = ornt[5];
4050: DMPlexSetCone(rdm, newp+7, coneNew);
4051: DMPlexSetConeOrientation(rdm, newp+7, orntNew);
4052: #if 1
4053: if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cMaxNew);
4054: for (p = 0; p < 6; ++p) {
4055: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
4056: }
4057: #endif
4058: }
4059: /* Hybrid cells have 6 faces: Front, Back, Sides */
4060: /*
4061: 3---------2---------2
4062: | | |
4063: | D 2 C |
4064: | | |
4065: 3----3----0----1----1
4066: | | |
4067: | A 0 B |
4068: | | |
4069: 0---------0---------1
4070: */
4071: for (c = cMax; c < cEnd; ++c) {
4072: const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4;
4073: const PetscInt *cone, *ornt, *fornt;
4074: PetscInt coneNew[6], orntNew[6];
4076: DMPlexGetCone(dm, c, &cone);
4077: DMPlexGetConeOrientation(dm, c, &ornt);
4078: DMPlexGetConeOrientation(dm, cone[0], &fornt);
4079: for (r = 0; r < 4; ++r) {
4080: PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
4081: PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
4082: PetscInt edgeB = (edgeA+3)%4;
4083: 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]);
4084: coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA;
4085: orntNew[0] = ornt[0];
4086: coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA;
4087: orntNew[1] = ornt[0];
4088: coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0);
4089: orntNew[(r+0)%4+2] = ornt[edgeA];
4090: coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA;
4091: orntNew[(r+1)%4+2] = 0;
4092: coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB;
4093: orntNew[(r+2)%4+2] = -2;
4094: coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1);
4095: orntNew[(r+3)%4+2] = ornt[edgeB];
4096: DMPlexSetCone(rdm, newp+r, coneNew);
4097: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
4098: #if 1
4099: if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+r, cMaxNew, cEndNew);
4100: for (p = 0; p < 2; ++p) {
4101: if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
4102: }
4103: for (p = 2; p < 6; ++p) {
4104: if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew);
4105: }
4106: #endif
4107: }
4108: }
4109: /* Interior split faces have 4 edges and the same cells as the parent */
4110: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
4111: PetscMalloc1((4 + maxSupportSize*2), &supportRef);
4112: for (f = fStart; f < fMax; ++f) {
4113: for (r = 0; r < 4; ++r) {
4114: /* TODO: This can come from GetFaces_Internal() */
4115: 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};
4116: const PetscInt newp = fStartNew + (f - fStart)*4 + r;
4117: const PetscInt *cone, *ornt, *support;
4118: PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s;
4120: DMPlexGetCone(dm, f, &cone);
4121: DMPlexGetConeOrientation(dm, f, &ornt);
4122: coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
4123: orntNew[(r+3)%4] = ornt[(r+3)%4];
4124: coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
4125: orntNew[(r+0)%4] = ornt[r];
4126: coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
4127: orntNew[(r+1)%4] = 0;
4128: coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
4129: orntNew[(r+2)%4] = -2;
4130: DMPlexSetCone(rdm, newp, coneNew);
4131: DMPlexSetConeOrientation(rdm, newp, orntNew);
4132: #if 1
4133: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4134: for (p = 0; p < 4; ++p) {
4135: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4136: }
4137: #endif
4138: DMPlexGetSupportSize(dm, f, &supportSize);
4139: DMPlexGetSupport(dm, f, &support);
4140: for (s = 0; s < supportSize; ++s) {
4141: PetscInt subf;
4142: DMPlexGetConeSize(dm, support[s], &coneSize);
4143: DMPlexGetCone(dm, support[s], &cone);
4144: DMPlexGetConeOrientation(dm, support[s], &ornt);
4145: for (c = 0; c < coneSize; ++c) {
4146: if (cone[c] == f) break;
4147: }
4148: subf = GetQuadSubfaceInverse_Static(ornt[c], r);
4149: if (support[s] < cMax) {
4150: supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
4151: } else {
4152: supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf;
4153: }
4154: }
4155: DMPlexSetSupport(rdm, newp, supportRef);
4156: #if 1
4157: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4158: for (p = 0; p < supportSize; ++p) {
4159: if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
4160: }
4161: #endif
4162: }
4163: }
4164: /* Interior faces have 4 edges and 2 cells */
4165: for (c = cStart; c < cMax; ++c) {
4166: 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};
4167: const PetscInt *cone, *ornt;
4168: PetscInt newp, coneNew[4], orntNew[4], supportNew[2];
4170: DMPlexGetCone(dm, c, &cone);
4171: DMPlexGetConeOrientation(dm, c, &ornt);
4172: /* A-D face */
4173: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
4174: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
4175: orntNew[0] = 0;
4176: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
4177: orntNew[1] = 0;
4178: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
4179: orntNew[2] = -2;
4180: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
4181: orntNew[3] = -2;
4182: DMPlexSetCone(rdm, newp, coneNew);
4183: DMPlexSetConeOrientation(rdm, newp, orntNew);
4184: #if 1
4185: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4186: for (p = 0; p < 4; ++p) {
4187: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4188: }
4189: #endif
4190: /* C-D face */
4191: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
4192: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
4193: orntNew[0] = 0;
4194: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
4195: orntNew[1] = 0;
4196: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
4197: orntNew[2] = -2;
4198: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
4199: orntNew[3] = -2;
4200: DMPlexSetCone(rdm, newp, coneNew);
4201: DMPlexSetConeOrientation(rdm, newp, orntNew);
4202: #if 1
4203: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4204: for (p = 0; p < 4; ++p) {
4205: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4206: }
4207: #endif
4208: /* B-C face */
4209: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
4210: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
4211: orntNew[0] = -2;
4212: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
4213: orntNew[1] = 0;
4214: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
4215: orntNew[2] = 0;
4216: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
4217: orntNew[3] = -2;
4218: DMPlexSetCone(rdm, newp, coneNew);
4219: DMPlexSetConeOrientation(rdm, newp, orntNew);
4220: #if 1
4221: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4222: for (p = 0; p < 4; ++p) {
4223: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4224: }
4225: #endif
4226: /* A-B face */
4227: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
4228: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
4229: orntNew[0] = -2;
4230: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
4231: orntNew[1] = 0;
4232: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
4233: orntNew[2] = 0;
4234: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0;
4235: orntNew[3] = -2;
4236: DMPlexSetCone(rdm, newp, coneNew);
4237: DMPlexSetConeOrientation(rdm, newp, orntNew);
4238: #if 1
4239: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4240: for (p = 0; p < 4; ++p) {
4241: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4242: }
4243: #endif
4244: /* E-F face */
4245: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
4246: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
4247: orntNew[0] = -2;
4248: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
4249: orntNew[1] = -2;
4250: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
4251: orntNew[2] = 0;
4252: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
4253: orntNew[3] = 0;
4254: DMPlexSetCone(rdm, newp, coneNew);
4255: DMPlexSetConeOrientation(rdm, newp, orntNew);
4256: #if 1
4257: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4258: for (p = 0; p < 4; ++p) {
4259: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4260: }
4261: #endif
4262: /* F-G face */
4263: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
4264: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
4265: orntNew[0] = -2;
4266: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
4267: orntNew[1] = -2;
4268: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
4269: orntNew[2] = 0;
4270: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
4271: orntNew[3] = 0;
4272: DMPlexSetCone(rdm, newp, coneNew);
4273: DMPlexSetConeOrientation(rdm, newp, orntNew);
4274: #if 1
4275: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4276: for (p = 0; p < 4; ++p) {
4277: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4278: }
4279: #endif
4280: /* G-H face */
4281: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
4282: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
4283: orntNew[0] = -2;
4284: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
4285: orntNew[1] = 0;
4286: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
4287: orntNew[2] = 0;
4288: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
4289: orntNew[3] = -2;
4290: DMPlexSetCone(rdm, newp, coneNew);
4291: DMPlexSetConeOrientation(rdm, newp, orntNew);
4292: #if 1
4293: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4294: for (p = 0; p < 4; ++p) {
4295: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4296: }
4297: #endif
4298: /* E-H face */
4299: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
4300: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
4301: orntNew[0] = -2;
4302: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
4303: orntNew[1] = -2;
4304: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
4305: orntNew[2] = 0;
4306: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1;
4307: orntNew[3] = 0;
4308: DMPlexSetCone(rdm, newp, coneNew);
4309: DMPlexSetConeOrientation(rdm, newp, orntNew);
4310: #if 1
4311: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4312: for (p = 0; p < 4; ++p) {
4313: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4314: }
4315: #endif
4316: /* A-E face */
4317: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
4318: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
4319: orntNew[0] = 0;
4320: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
4321: orntNew[1] = 0;
4322: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
4323: orntNew[2] = -2;
4324: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
4325: orntNew[3] = -2;
4326: DMPlexSetCone(rdm, newp, coneNew);
4327: DMPlexSetConeOrientation(rdm, newp, orntNew);
4328: #if 1
4329: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4330: for (p = 0; p < 4; ++p) {
4331: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4332: }
4333: #endif
4334: /* D-F face */
4335: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
4336: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
4337: orntNew[0] = -2;
4338: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
4339: orntNew[1] = 0;
4340: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
4341: orntNew[2] = 0;
4342: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2;
4343: orntNew[3] = -2;
4344: DMPlexSetCone(rdm, newp, coneNew);
4345: DMPlexSetConeOrientation(rdm, newp, orntNew);
4346: #if 1
4347: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4348: for (p = 0; p < 4; ++p) {
4349: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4350: }
4351: #endif
4352: /* C-G face */
4353: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
4354: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4;
4355: orntNew[0] = -2;
4356: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
4357: orntNew[1] = -2;
4358: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
4359: orntNew[2] = 0;
4360: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
4361: orntNew[3] = 0;
4362: DMPlexSetCone(rdm, newp, coneNew);
4363: DMPlexSetConeOrientation(rdm, newp, orntNew);
4364: #if 1
4365: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4366: for (p = 0; p < 4; ++p) {
4367: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4368: }
4369: #endif
4370: /* B-H face */
4371: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
4372: coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5;
4373: orntNew[0] = 0;
4374: coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3;
4375: orntNew[1] = -2;
4376: coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
4377: orntNew[2] = -2;
4378: coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
4379: orntNew[3] = 0;
4380: DMPlexSetCone(rdm, newp, coneNew);
4381: DMPlexSetConeOrientation(rdm, newp, orntNew);
4382: #if 1
4383: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4384: for (p = 0; p < 4; ++p) {
4385: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4386: }
4387: #endif
4388: for (r = 0; r < 12; ++r) {
4389: newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
4390: supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
4391: supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
4392: DMPlexSetSupport(rdm, newp, supportNew);
4393: #if 1
4394: if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
4395: for (p = 0; p < 2; ++p) {
4396: if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
4397: }
4398: #endif
4399: }
4400: }
4401: /* Hybrid split faces have 4 edges and same cells */
4402: for (f = fMax; f < fEnd; ++f) {
4403: const PetscInt *cone, *ornt, *support;
4404: PetscInt coneNew[4], orntNew[4];
4405: PetscInt supportNew[2], size, s, c;
4407: DMPlexGetCone(dm, f, &cone);
4408: DMPlexGetConeOrientation(dm, f, &ornt);
4409: DMPlexGetSupportSize(dm, f, &size);
4410: DMPlexGetSupport(dm, f, &support);
4411: for (r = 0; r < 2; ++r) {
4412: const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
4414: coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
4415: orntNew[0] = ornt[0];
4416: coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
4417: orntNew[1] = ornt[1];
4418: coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
4419: orntNew[2+r] = 0;
4420: coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
4421: orntNew[3-r] = 0;
4422: DMPlexSetCone(rdm, newp, coneNew);
4423: DMPlexSetConeOrientation(rdm, newp, orntNew);
4424: #if 1
4425: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
4426: for (p = 0; p < 2; ++p) {
4427: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4428: }
4429: for (p = 2; p < 4; ++p) {
4430: if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
4431: }
4432: #endif
4433: for (s = 0; s < size; ++s) {
4434: const PetscInt *coneCell, *orntCell, *fornt;
4436: DMPlexGetCone(dm, support[s], &coneCell);
4437: DMPlexGetConeOrientation(dm, support[s], &orntCell);
4438: for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
4439: if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]);
4440: DMPlexGetConeOrientation(dm, coneCell[0], &fornt);
4441: supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%4;
4442: }
4443: DMPlexSetSupport(rdm, newp, supportNew);
4444: #if 1
4445: if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
4446: for (p = 0; p < size; ++p) {
4447: if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
4448: }
4449: #endif
4450: }
4451: }
4452: /* Hybrid cell faces have 4 edges and 2 cells */
4453: for (c = cMax; c < cEnd; ++c) {
4454: PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
4455: const PetscInt *cone, *ornt;
4456: PetscInt coneNew[4], orntNew[4];
4457: PetscInt supportNew[2];
4459: DMPlexGetCone(dm, c, &cone);
4460: DMPlexGetConeOrientation(dm, c, &ornt);
4461: for (r = 0; r < 4; ++r) {
4462: coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
4463: orntNew[0] = 0;
4464: coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
4465: orntNew[1] = 0;
4466: coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
4467: orntNew[2] = 0;
4468: coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
4469: orntNew[3] = 0;
4470: DMPlexSetCone(rdm, newp+r, coneNew);
4471: DMPlexSetConeOrientation(rdm, newp+r, orntNew);
4472: #if 1
4473: if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
4474: for (p = 0; p < 2; ++p) {
4475: if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
4476: }
4477: for (p = 2; p < 4; ++p) {
4478: if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
4479: }
4480: #endif
4481: supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
4482: supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
4483: DMPlexSetSupport(rdm, newp+r, supportNew);
4484: #if 1
4485: if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
4486: for (p = 0; p < 2; ++p) {
4487: if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
4488: }
4489: #endif
4490: }
4491: }
4492: /* Interior split edges have 2 vertices and the same faces as the parent */
4493: DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);
4494: for (e = eStart; e < eMax; ++e) {
4495: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
4497: for (r = 0; r < 2; ++r) {
4498: const PetscInt newp = eStartNew + (e - eStart)*2 + r;
4499: const PetscInt *cone, *ornt, *support;
4500: PetscInt coneNew[2], coneSize, c, supportSize, s;
4502: DMPlexGetCone(dm, e, &cone);
4503: coneNew[0] = vStartNew + (cone[0] - vStart);
4504: coneNew[1] = vStartNew + (cone[1] - vStart);
4505: coneNew[(r+1)%2] = newv;
4506: DMPlexSetCone(rdm, newp, coneNew);
4507: #if 1
4508: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
4509: for (p = 0; p < 2; ++p) {
4510: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
4511: }
4512: #endif
4513: DMPlexGetSupportSize(dm, e, &supportSize);
4514: DMPlexGetSupport(dm, e, &support);
4515: for (s = 0; s < supportSize; ++s) {
4516: DMPlexGetConeSize(dm, support[s], &coneSize);
4517: DMPlexGetCone(dm, support[s], &cone);
4518: DMPlexGetConeOrientation(dm, support[s], &ornt);
4519: for (c = 0; c < coneSize; ++c) {
4520: if (cone[c] == e) break;
4521: }
4522: if (support[s] < fMax) {
4523: supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
4524: } else {
4525: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
4526: }
4527: }
4528: DMPlexSetSupport(rdm, newp, supportRef);
4529: #if 1
4530: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
4531: for (p = 0; p < supportSize; ++p) {
4532: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
4533: }
4534: #endif
4535: }
4536: }
4537: /* Interior face edges have 2 vertices and 2+cells faces */
4538: for (f = fStart; f < fMax; ++f) {
4539: 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};
4540: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
4541: const PetscInt *cone, *coneCell, *orntCell, *support;
4542: PetscInt coneNew[2], coneSize, c, supportSize, s;
4544: DMPlexGetCone(dm, f, &cone);
4545: for (r = 0; r < 4; ++r) {
4546: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
4548: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
4549: coneNew[1] = newv;
4550: DMPlexSetCone(rdm, newp, coneNew);
4551: #if 1
4552: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
4553: for (p = 0; p < 2; ++p) {
4554: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
4555: }
4556: #endif
4557: DMPlexGetSupportSize(dm, f, &supportSize);
4558: DMPlexGetSupport(dm, f, &support);
4559: supportRef[0] = fStartNew + (f - fStart)*4 + r;
4560: supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
4561: for (s = 0; s < supportSize; ++s) {
4562: DMPlexGetConeSize(dm, support[s], &coneSize);
4563: DMPlexGetCone(dm, support[s], &coneCell);
4564: DMPlexGetConeOrientation(dm, support[s], &orntCell);
4565: for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
4566: if (support[s] < cMax) {
4567: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
4568: } else {
4569: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r);
4570: }
4571: }
4572: DMPlexSetSupport(rdm, newp, supportRef);
4573: #if 1
4574: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
4575: for (p = 0; p < 2+supportSize; ++p) {
4576: if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
4577: }
4578: #endif
4579: }
4580: }
4581: /* Interior cell edges have 2 vertices and 4 faces */
4582: for (c = cStart; c < cMax; ++c) {
4583: 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};
4584: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
4585: const PetscInt *cone;
4586: PetscInt coneNew[2], supportNew[4];
4588: DMPlexGetCone(dm, c, &cone);
4589: for (r = 0; r < 6; ++r) {
4590: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
4592: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
4593: coneNew[1] = newv;
4594: DMPlexSetCone(rdm, newp, coneNew);
4595: #if 1
4596: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
4597: for (p = 0; p < 2; ++p) {
4598: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
4599: }
4600: #endif
4601: for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
4602: DMPlexSetSupport(rdm, newp, supportNew);
4603: #if 1
4604: if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
4605: for (p = 0; p < 4; ++p) {
4606: if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fMaxNew);
4607: }
4608: #endif
4609: }
4610: }
4611: /* Hybrid edges have two vertices and the same faces */
4612: for (e = eMax; e < eEnd; ++e) {
4613: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
4614: const PetscInt *cone, *support, *fcone;
4615: PetscInt coneNew[2], size, fsize, s;
4617: DMPlexGetCone(dm, e, &cone);
4618: DMPlexGetSupportSize(dm, e, &size);
4619: DMPlexGetSupport(dm, e, &support);
4620: coneNew[0] = vStartNew + (cone[0] - vStart);
4621: coneNew[1] = vStartNew + (cone[1] - vStart);
4622: DMPlexSetCone(rdm, newp, coneNew);
4623: #if 1
4624: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
4625: for (p = 0; p < 2; ++p) {
4626: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
4627: }
4628: #endif
4629: for (s = 0; s < size; ++s) {
4630: DMPlexGetConeSize(dm, support[s], &fsize);
4631: DMPlexGetCone(dm, support[s], &fcone);
4632: for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
4633: if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]);
4634: supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
4635: }
4636: DMPlexSetSupport(rdm, newp, supportRef);
4637: #if 1
4638: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
4639: for (p = 0; p < size; ++p) {
4640: if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
4641: }
4642: #endif
4643: }
4644: /* Hybrid face edges have 2 vertices and 2+cells faces */
4645: for (f = fMax; f < fEnd; ++f) {
4646: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
4647: const PetscInt *cone, *support, *ccone, *cornt;
4648: PetscInt coneNew[2], size, csize, s;
4650: DMPlexGetCone(dm, f, &cone);
4651: DMPlexGetSupportSize(dm, f, &size);
4652: DMPlexGetSupport(dm, f, &support);
4653: coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
4654: coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
4655: DMPlexSetCone(rdm, newp, coneNew);
4656: #if 1
4657: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
4658: for (p = 0; p < 2; ++p) {
4659: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
4660: }
4661: #endif
4662: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
4663: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
4664: for (s = 0; s < size; ++s) {
4665: DMPlexGetConeSize(dm, support[s], &csize);
4666: DMPlexGetCone(dm, support[s], &ccone);
4667: DMPlexGetConeOrientation(dm, support[s], &cornt);
4668: for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
4669: if ((c < 2) || (c >= csize)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Hybrid face %d is not in cone of hybrid cell %d", f, support[s]);
4670: supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadSubfaceInverse_Static(cornt[0], c-2);
4671: }
4672: DMPlexSetSupport(rdm, newp, supportRef);
4673: #if 1
4674: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
4675: for (p = 0; p < 2+size; ++p) {
4676: if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
4677: }
4678: #endif
4679: }
4680: /* Hybrid cell edges have 2 vertices and 4 faces */
4681: for (c = cMax; c < cEnd; ++c) {
4682: const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
4683: const PetscInt *cone, *support;
4684: PetscInt coneNew[2], size;
4686: DMPlexGetCone(dm, c, &cone);
4687: DMPlexGetSupportSize(dm, c, &size);
4688: DMPlexGetSupport(dm, c, &support);
4689: coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
4690: coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
4691: DMPlexSetCone(rdm, newp, coneNew);
4692: #if 1
4693: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
4694: for (p = 0; p < 2; ++p) {
4695: if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
4696: }
4697: #endif
4698: supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
4699: supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
4700: supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
4701: supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
4702: DMPlexSetSupport(rdm, newp, supportRef);
4703: #if 1
4704: if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
4705: for (p = 0; p < 4; ++p) {
4706: if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
4707: }
4708: #endif
4709: }
4710: /* Interior vertices have identical supports */
4711: for (v = vStart; v < vEnd; ++v) {
4712: const PetscInt newp = vStartNew + (v - vStart);
4713: const PetscInt *support, *cone;
4714: PetscInt size, s;
4716: DMPlexGetSupportSize(dm, v, &size);
4717: DMPlexGetSupport(dm, v, &support);
4718: for (s = 0; s < size; ++s) {
4719: PetscInt r = 0;
4721: DMPlexGetCone(dm, support[s], &cone);
4722: if (cone[1] == v) r = 1;
4723: if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4724: else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
4725: }
4726: DMPlexSetSupport(rdm, newp, supportRef);
4727: #if 1
4728: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4729: for (p = 0; p < size; ++p) {
4730: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
4731: }
4732: #endif
4733: }
4734: /* Interior edge vertices have 2 + faces supports */
4735: for (e = eStart; e < eMax; ++e) {
4736: const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
4737: const PetscInt *cone, *support;
4738: PetscInt size, s;
4740: DMPlexGetSupportSize(dm, e, &size);
4741: DMPlexGetSupport(dm, e, &support);
4742: supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4743: supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4744: for (s = 0; s < size; ++s) {
4745: PetscInt r;
4747: DMPlexGetCone(dm, support[s], &cone);
4748: for (r = 0; r < 4; ++r) if (cone[r] == e) break;
4749: if (support[s] < fMax) {
4750: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
4751: } else {
4752: supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
4753: }
4754: }
4755: DMPlexSetSupport(rdm, newp, supportRef);
4756: #if 1
4757: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4758: for (p = 0; p < 2+size; ++p) {
4759: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
4760: }
4761: #endif
4762: }
4763: /* Interior face vertices have 4 + cells supports */
4764: for (f = fStart; f < fMax; ++f) {
4765: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
4766: const PetscInt *cone, *support;
4767: PetscInt size, s;
4769: DMPlexGetSupportSize(dm, f, &size);
4770: DMPlexGetSupport(dm, f, &support);
4771: for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
4772: for (s = 0; s < size; ++s) {
4773: PetscInt r;
4775: DMPlexGetCone(dm, support[s], &cone);
4776: for (r = 0; r < 6; ++r) if (cone[r] == f) break;
4777: if (support[s] < cMax) {
4778: supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
4779: } else {
4780: supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
4781: }
4782: }
4783: DMPlexSetSupport(rdm, newp, supportRef);
4784: #if 1
4785: if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4786: for (p = 0; p < 4+size; ++p) {
4787: if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
4788: }
4789: #endif
4790: }
4791: /* Cell vertices have 6 supports */
4792: for (c = cStart; c < cMax; ++c) {
4793: const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
4794: PetscInt supportNew[6];
4796: for (r = 0; r < 6; ++r) {
4797: supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
4798: }
4799: DMPlexSetSupport(rdm, newp, supportNew);
4800: }
4801: PetscFree(supportRef);
4802: break;
4803: default:
4804: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
4805: }
4806: return(0);
4807: }
4811: static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
4812: {
4813: PetscSection coordSection, coordSectionNew;
4814: Vec coordinates, coordinatesNew;
4815: PetscScalar *coords, *coordsNew;
4816: const PetscInt numVertices = depthSize ? depthSize[0] : 0;
4817: PetscInt dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
4821: DMPlexGetDimension(dm, &dim);
4822: DMPlexGetDepth(dm, &depth);
4823: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
4824: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
4825: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
4826: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
4827: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);
4828: if (refiner) {GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);}
4829: GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);
4830: DMGetCoordinateSection(dm, &coordSection);
4831: PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);
4832: PetscSectionSetNumFields(coordSectionNew, 1);
4833: PetscSectionSetFieldComponents(coordSectionNew, 0, dim);
4834: PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);
4835: if (cMax < 0) cMax = cEnd;
4836: if (fMax < 0) fMax = fEnd;
4837: if (eMax < 0) eMax = eEnd;
4838: /* All vertices have the dim coordinates */
4839: for (v = vStartNew; v < vStartNew+numVertices; ++v) {
4840: PetscSectionSetDof(coordSectionNew, v, dim);
4841: PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);
4842: }
4843: PetscSectionSetUp(coordSectionNew);
4844: DMSetCoordinateSection(rdm, coordSectionNew);
4845: DMGetCoordinatesLocal(dm, &coordinates);
4846: PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);
4847: VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);
4848: PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");
4849: VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);
4850: VecSetFromOptions(coordinatesNew);
4851: VecGetArray(coordinates, &coords);
4852: VecGetArray(coordinatesNew, &coordsNew);
4853: switch (refiner) {
4854: case 0: break;
4855: case 6: /* Hex 3D */
4856: case 8: /* Hybrid Hex 3D */
4857: /* Face vertices have the average of corner coordinates */
4858: for (f = fStart; f < fMax; ++f) {
4859: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
4860: PetscInt *cone = NULL;
4861: PetscInt closureSize, coneSize = 0, off[8], offnew, p, d;
4863: DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);
4864: for (p = 0; p < closureSize*2; p += 2) {
4865: const PetscInt point = cone[p];
4866: if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
4867: }
4868: for (v = 0; v < coneSize; ++v) {
4869: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
4870: }
4871: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
4872: for (d = 0; d < dim; ++d) {
4873: coordsNew[offnew+d] = 0.0;
4874: for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
4875: coordsNew[offnew+d] /= coneSize;
4876: }
4877: DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);
4878: }
4879: case 2: /* Hex 2D */
4880: /* Cell vertices have the average of corner coordinates */
4881: for (c = cStart; c < cMax; ++c) {
4882: const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
4883: PetscInt *cone = NULL;
4884: PetscInt closureSize, coneSize = 0, off[8], offnew, p, d;
4886: DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);
4887: for (p = 0; p < closureSize*2; p += 2) {
4888: const PetscInt point = cone[p];
4889: if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
4890: }
4891: for (v = 0; v < coneSize; ++v) {
4892: PetscSectionGetOffset(coordSection, cone[v], &off[v]);
4893: }
4894: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
4895: for (d = 0; d < dim; ++d) {
4896: coordsNew[offnew+d] = 0.0;
4897: for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
4898: coordsNew[offnew+d] /= coneSize;
4899: }
4900: DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);
4901: }
4902: case 1: /* Simplicial 2D */
4903: case 3: /* Hybrid Simplicial 2D */
4904: case 5: /* Simplicial 3D */
4905: case 7: /* Hybrid Simplicial 3D */
4906: /* Edge vertices have the average of endpoint coordinates */
4907: for (e = eStart; e < eMax; ++e) {
4908: const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
4909: const PetscInt *cone;
4910: PetscInt coneSize, offA, offB, offnew, d;
4912: DMPlexGetConeSize(dm, e, &coneSize);
4913: if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
4914: DMPlexGetCone(dm, e, &cone);
4915: PetscSectionGetOffset(coordSection, cone[0], &offA);
4916: PetscSectionGetOffset(coordSection, cone[1], &offB);
4917: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
4918: for (d = 0; d < dim; ++d) {
4919: coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]);
4920: }
4921: }
4922: /* Old vertices have the same coordinates */
4923: for (v = vStart; v < vEnd; ++v) {
4924: const PetscInt newv = vStartNew + (v - vStart);
4925: PetscInt off, offnew, d;
4927: PetscSectionGetOffset(coordSection, v, &off);
4928: PetscSectionGetOffset(coordSectionNew, newv, &offnew);
4929: for (d = 0; d < dim; ++d) {
4930: coordsNew[offnew+d] = coords[off+d];
4931: }
4932: }
4933: break;
4934: default:
4935: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
4936: }
4937: VecRestoreArray(coordinates, &coords);
4938: VecRestoreArray(coordinatesNew, &coordsNew);
4939: DMSetCoordinatesLocal(rdm, coordinatesNew);
4940: VecDestroy(&coordinatesNew);
4941: PetscSectionDestroy(&coordSectionNew);
4942: return(0);
4943: }
4947: static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
4948: {
4949: PetscInt numRoots, numLeaves, l;
4950: const PetscInt *localPoints;
4951: const PetscSFNode *remotePoints;
4952: PetscInt *localPointsNew;
4953: PetscSFNode *remotePointsNew;
4954: PetscInt *ranks, *ranksNew;
4955: PetscErrorCode ierr;
4958: PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);
4959: PetscMalloc1(numLeaves, &ranks);
4960: for (l = 0; l < numLeaves; ++l) {
4961: ranks[l] = remotePoints[l].rank;
4962: }
4963: PetscSortRemoveDupsInt(&numLeaves, ranks);
4964: PetscMalloc1(numLeaves, &ranksNew);
4965: PetscMalloc1(numLeaves, &localPointsNew);
4966: PetscMalloc1(numLeaves, &remotePointsNew);
4967: for (l = 0; l < numLeaves; ++l) {
4968: ranksNew[l] = ranks[l];
4969: localPointsNew[l] = l;
4970: remotePointsNew[l].index = 0;
4971: remotePointsNew[l].rank = ranksNew[l];
4972: }
4973: PetscFree(ranks);
4974: ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);
4975: PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);
4976: PetscSFSetFromOptions(*sfProcess);
4977: PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);
4978: return(0);
4979: }
4983: static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
4984: {
4985: PetscSF sf, sfNew, sfProcess;
4986: IS processRanks;
4987: MPI_Datatype depthType;
4988: PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m;
4989: const PetscInt *localPoints, *neighbors;
4990: const PetscSFNode *remotePoints;
4991: PetscInt *localPointsNew;
4992: PetscSFNode *remotePointsNew;
4993: PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
4994: PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
4995: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
4996: PetscErrorCode ierr;
4999: DMPlexGetChart(rdm, &pStartNew, &pEndNew);
5000: DMPlexGetDepth(dm, &depth);
5001: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
5002: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
5003: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
5004: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
5005: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
5006: if (refiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
5007: DMGetPointSF(dm, &sf);
5008: DMGetPointSF(rdm, &sfNew);
5009: /* Caculate size of new SF */
5010: PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);
5011: if (numRoots < 0) return(0);
5012: for (l = 0; l < numLeaves; ++l) {
5013: const PetscInt p = localPoints[l];
5015: switch (refiner) {
5016: case 1:
5017: /* Simplicial 2D */
5018: if ((p >= vStart) && (p < vEnd)) {
5019: /* Old vertices stay the same */
5020: ++numLeavesNew;
5021: } else if ((p >= fStart) && (p < fEnd)) {
5022: /* Old faces add new faces and vertex */
5023: numLeavesNew += 2 + 1;
5024: } else if ((p >= cStart) && (p < cEnd)) {
5025: /* Old cells add new cells and interior faces */
5026: numLeavesNew += 4 + 3;
5027: }
5028: break;
5029: case 2:
5030: /* Hex 2D */
5031: if ((p >= vStart) && (p < vEnd)) {
5032: /* Old vertices stay the same */
5033: ++numLeavesNew;
5034: } else if ((p >= fStart) && (p < fEnd)) {
5035: /* Old faces add new faces and vertex */
5036: numLeavesNew += 2 + 1;
5037: } else if ((p >= cStart) && (p < cEnd)) {
5038: /* Old cells add new cells, interior faces, and vertex */
5039: numLeavesNew += 4 + 4 + 1;
5040: }
5041: break;
5042: case 5:
5043: /* Simplicial 3D */
5044: if ((p >= vStart) && (p < vEnd)) {
5045: /* Old vertices stay the same */
5046: ++numLeavesNew;
5047: } else if ((p >= eStart) && (p < eEnd)) {
5048: /* Old edges add new edges and vertex */
5049: numLeavesNew += 2 + 1;
5050: } else if ((p >= fStart) && (p < fEnd)) {
5051: /* Old faces add new faces and face edges */
5052: numLeavesNew += 4 + 3;
5053: } else if ((p >= cStart) && (p < cEnd)) {
5054: /* Old cells add new cells and interior faces and edges */
5055: numLeavesNew += 8 + 8 + 1;
5056: }
5057: break;
5058: case 7:
5059: /* Hybrid Simplicial 3D */
5060: if ((p >= vStart) && (p < vEnd)) {
5061: /* Interior vertices stay the same */
5062: ++numLeavesNew;
5063: } else if ((p >= eStart) && (p < eMax)) {
5064: /* Interior edges add new edges and vertex */
5065: numLeavesNew += 2 + 1;
5066: } else if ((p >= eMax) && (p < eEnd)) {
5067: /* Hybrid edges stay the same */
5068: ++numLeavesNew;
5069: } else if ((p >= fStart) && (p < fMax)) {
5070: /* Interior faces add new faces and edges */
5071: numLeavesNew += 4 + 3;
5072: } else if ((p >= fMax) && (p < fEnd)) {
5073: /* Hybrid faces add new faces and edges */
5074: numLeavesNew += 2 + 1;
5075: } else if ((p >= cStart) && (p < cMax)) {
5076: /* Interior cells add new cells, faces, and edges */
5077: numLeavesNew += 8 + 8 + 1;
5078: } else if ((p >= cMax) && (p < cEnd)) {
5079: /* Hybrid cells add new cells and faces */
5080: numLeavesNew += 4 + 3;
5081: }
5082: break;
5083: case 6:
5084: /* Hex 3D */
5085: if ((p >= vStart) && (p < vEnd)) {
5086: /* Old vertices stay the same */
5087: ++numLeavesNew;
5088: } else if ((p >= eStart) && (p < eEnd)) {
5089: /* Old edges add new edges, and vertex */
5090: numLeavesNew += 2 + 1;
5091: } else if ((p >= fStart) && (p < fEnd)) {
5092: /* Old faces add new faces, edges, and vertex */
5093: numLeavesNew += 4 + 4 + 1;
5094: } else if ((p >= cStart) && (p < cEnd)) {
5095: /* Old cells add new cells, faces, edges, and vertex */
5096: numLeavesNew += 8 + 12 + 6 + 1;
5097: }
5098: break;
5099: case 8:
5100: /* Hybrid Hex 3D */
5101: if ((p >= vStart) && (p < vEnd)) {
5102: /* Old vertices stay the same */
5103: ++numLeavesNew;
5104: } else if ((p >= eStart) && (p < eMax)) {
5105: /* Interior edges add new edges, and vertex */
5106: numLeavesNew += 2 + 1;
5107: } else if ((p >= eMax) && (p < eEnd)) {
5108: /* Hybrid edges stay the same */
5109: ++numLeavesNew;
5110: } else if ((p >= fStart) && (p < fMax)) {
5111: /* Interior faces add new faces, edges, and vertex */
5112: numLeavesNew += 4 + 4 + 1;
5113: } else if ((p >= fMax) && (p < fEnd)) {
5114: /* Hybrid faces add new faces and edges */
5115: numLeavesNew += 2 + 1;
5116: } else if ((p >= cStart) && (p < cMax)) {
5117: /* Interior cells add new cells, faces, edges, and vertex */
5118: numLeavesNew += 8 + 12 + 6 + 1;
5119: } else if ((p >= cStart) && (p < cEnd)) {
5120: /* Hybrid cells add new cells, faces, and edges */
5121: numLeavesNew += 4 + 4 + 1;
5122: }
5123: break;
5124: default:
5125: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
5126: }
5127: }
5128: /* Communicate depthSizes for each remote rank */
5129: DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);
5130: ISGetLocalSize(processRanks, &numNeighbors);
5131: PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);
5132: PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);
5133: MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);
5134: MPI_Type_commit(&depthType);
5135: PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);
5136: PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);
5137: for (n = 0; n < numNeighbors; ++n) {
5138: GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);
5139: }
5140: depthSizeOld[depth] = cMax;
5141: depthSizeOld[0] = vMax;
5142: depthSizeOld[depth-1] = fMax;
5143: depthSizeOld[1] = eMax;
5145: PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);
5146: PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);
5148: depthSizeOld[depth] = cEnd - cStart;
5149: depthSizeOld[0] = vEnd - vStart;
5150: depthSizeOld[depth-1] = fEnd - fStart;
5151: depthSizeOld[1] = eEnd - eStart;
5153: PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);
5154: PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);
5155: for (n = 0; n < numNeighbors; ++n) {
5156: GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);
5157: }
5158: MPI_Type_free(&depthType);
5159: PetscSFDestroy(&sfProcess);
5160: /* Calculate new point SF */
5161: PetscMalloc1(numLeavesNew, &localPointsNew);
5162: PetscMalloc1(numLeavesNew, &remotePointsNew);
5163: ISGetIndices(processRanks, &neighbors);
5164: for (l = 0, m = 0; l < numLeaves; ++l) {
5165: PetscInt p = localPoints[l];
5166: PetscInt rp = remotePoints[l].index, n;
5167: PetscMPIInt rrank = remotePoints[l].rank;
5169: PetscFindInt(rrank, numNeighbors, neighbors, &n);
5170: if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
5171: switch (refiner) {
5172: case 1:
5173: /* Simplicial 2D */
5174: if ((p >= vStart) && (p < vEnd)) {
5175: /* Old vertices stay the same */
5176: localPointsNew[m] = vStartNew + (p - vStart);
5177: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5178: remotePointsNew[m].rank = rrank;
5179: ++m;
5180: } else if ((p >= fStart) && (p < fEnd)) {
5181: /* Old faces add new faces and vertex */
5182: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
5183: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5184: remotePointsNew[m].rank = rrank;
5185: ++m;
5186: for (r = 0; r < 2; ++r, ++m) {
5187: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
5188: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
5189: remotePointsNew[m].rank = rrank;
5190: }
5191: } else if ((p >= cStart) && (p < cEnd)) {
5192: /* Old cells add new cells and interior faces */
5193: for (r = 0; r < 4; ++r, ++m) {
5194: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
5195: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5196: remotePointsNew[m].rank = rrank;
5197: }
5198: for (r = 0; r < 3; ++r, ++m) {
5199: localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
5200: remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
5201: remotePointsNew[m].rank = rrank;
5202: }
5203: }
5204: break;
5205: case 2:
5206: /* Hex 2D */
5207: if ((p >= vStart) && (p < vEnd)) {
5208: /* Old vertices stay the same */
5209: localPointsNew[m] = vStartNew + (p - vStart);
5210: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5211: remotePointsNew[m].rank = rrank;
5212: ++m;
5213: } else if ((p >= fStart) && (p < fEnd)) {
5214: /* Old faces add new faces and vertex */
5215: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
5216: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5217: remotePointsNew[m].rank = rrank;
5218: ++m;
5219: for (r = 0; r < 2; ++r, ++m) {
5220: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
5221: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
5222: remotePointsNew[m].rank = rrank;
5223: }
5224: } else if ((p >= cStart) && (p < cEnd)) {
5225: /* Old cells add new cells, interior faces, and vertex */
5226: for (r = 0; r < 4; ++r, ++m) {
5227: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
5228: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5229: remotePointsNew[m].rank = rrank;
5230: }
5231: for (r = 0; r < 4; ++r, ++m) {
5232: localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
5233: remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r;
5234: remotePointsNew[m].rank = rrank;
5235: }
5236: for (r = 0; r < 1; ++r, ++m) {
5237: localPointsNew[m] = vStartNew + (fEnd - fStart) + (p - cStart) + r;
5238: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
5239: remotePointsNew[m].rank = rrank;
5240: }
5241: }
5242: break;
5243: case 3:
5244: /* Hybrid simplicial 2D */
5245: if ((p >= vStart) && (p < vEnd)) {
5246: /* Old vertices stay the same */
5247: localPointsNew[m] = vStartNew + (p - vStart);
5248: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5249: remotePointsNew[m].rank = rrank;
5250: ++m;
5251: } else if ((p >= fStart) && (p < fMax)) {
5252: /* Old interior faces add new faces and vertex */
5253: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart);
5254: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5255: remotePointsNew[m].rank = rrank;
5256: ++m;
5257: for (r = 0; r < 2; ++r, ++m) {
5258: localPointsNew[m] = fStartNew + (p - fStart)*2 + r;
5259: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
5260: remotePointsNew[m].rank = rrank;
5261: }
5262: } else if ((p >= fMax) && (p < fEnd)) {
5263: /* Old hybrid faces stay the same */
5264: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax);
5265: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
5266: remotePointsNew[m].rank = rrank;
5267: ++m;
5268: } else if ((p >= cStart) && (p < cMax)) {
5269: /* Old interior cells add new cells and interior faces */
5270: for (r = 0; r < 4; ++r, ++m) {
5271: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
5272: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5273: remotePointsNew[m].rank = rrank;
5274: }
5275: for (r = 0; r < 3; ++r, ++m) {
5276: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r;
5277: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
5278: remotePointsNew[m].rank = rrank;
5279: }
5280: } else if ((p >= cStart) && (p < cMax)) {
5281: /* Old hybrid cells add new cells and hybrid face */
5282: for (r = 0; r < 2; ++r, ++m) {
5283: localPointsNew[m] = cStartNew + (p - cStart)*4 + r;
5284: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5285: remotePointsNew[m].rank = rrank;
5286: }
5287: localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
5288: 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]);
5289: remotePointsNew[m].rank = rrank;
5290: ++m;
5291: }
5292: break;
5293: case 5:
5294: /* Simplicial 3D */
5295: if ((p >= vStart) && (p < vEnd)) {
5296: /* Old vertices stay the same */
5297: localPointsNew[m] = vStartNew + (p - vStart);
5298: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5299: remotePointsNew[m].rank = rrank;
5300: ++m;
5301: } else if ((p >= eStart) && (p < eEnd)) {
5302: /* Old edges add new edges and vertex */
5303: for (r = 0; r < 2; ++r, ++m) {
5304: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
5305: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
5306: remotePointsNew[m].rank = rrank;
5307: }
5308: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
5309: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
5310: remotePointsNew[m].rank = rrank;
5311: ++m;
5312: } else if ((p >= fStart) && (p < fEnd)) {
5313: /* Old faces add new faces and face edges */
5314: for (r = 0; r < 4; ++r, ++m) {
5315: localPointsNew[m] = fStartNew + (p - fStart)*4 + r;
5316: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
5317: remotePointsNew[m].rank = rrank;
5318: }
5319: for (r = 0; r < 3; ++r, ++m) {
5320: localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
5321: remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r;
5322: remotePointsNew[m].rank = rrank;
5323: }
5324: } else if ((p >= cStart) && (p < cEnd)) {
5325: /* Old cells add new cells and interior faces and edges */
5326: for (r = 0; r < 8; ++r, ++m) {
5327: localPointsNew[m] = cStartNew + (p - cStart)*8 + r;
5328: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
5329: remotePointsNew[m].rank = rrank;
5330: }
5331: for (r = 0; r < 8; ++r, ++m) {
5332: localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
5333: remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r;
5334: remotePointsNew[m].rank = rrank;
5335: }
5336: for (r = 0; r < 1; ++r, ++m) {
5337: localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
5338: remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r;
5339: remotePointsNew[m].rank = rrank;
5340: }
5341: }
5342: break;
5343: case 7:
5344: /* Hybrid Simplicial 3D */
5345: if ((p >= vStart) && (p < vEnd)) {
5346: /* Interior vertices stay the same */
5347: localPointsNew[m] = vStartNew + (p - vStart);
5348: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5349: remotePointsNew[m].rank = rrank;
5350: ++m;
5351: } else if ((p >= eStart) && (p < eMax)) {
5352: /* Interior edges add new edges and vertex */
5353: for (r = 0; r < 2; ++r, ++m) {
5354: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
5355: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
5356: remotePointsNew[m].rank = rrank;
5357: }
5358: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
5359: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
5360: remotePointsNew[m].rank = rrank;
5361: ++m;
5362: } else if ((p >= eMax) && (p < eEnd)) {
5363: /* Hybrid edges stay the same */
5364: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
5365: remotePointsNew[m].index = rvStartNew[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]);
5366: remotePointsNew[m].rank = rrank;
5367: ++m;
5368: } else if ((p >= fStart) && (p < fMax)) {
5369: /* Interior faces add new faces and edges */
5370: for (r = 0; r < 4; ++r, ++m) {
5371: localPointsNew[m] = fStartNew + (p - fStart)*4 + r;
5372: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
5373: remotePointsNew[m].rank = rrank;
5374: }
5375: for (r = 0; r < 3; ++r, ++m) {
5376: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
5377: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
5378: remotePointsNew[m].rank = rrank;
5379: }
5380: } else if ((p >= fMax) && (p < fEnd)) {
5381: /* Hybrid faces add new faces and edges */
5382: for (r = 0; r < 2; ++r, ++m) {
5383: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
5384: 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;
5385: remotePointsNew[m].rank = rrank;
5386: }
5387: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
5388: 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)+depth-1]);
5389: remotePointsNew[m].rank = rrank;
5390: ++m;
5391: } else if ((p >= cStart) && (p < cMax)) {
5392: /* Interior cells add new cells, faces, and edges */
5393: for (r = 0; r < 8; ++r, ++m) {
5394: localPointsNew[m] = cStartNew + (p - cStart)*8 + r;
5395: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
5396: remotePointsNew[m].rank = rrank;
5397: }
5398: for (r = 0; r < 8; ++r, ++m) {
5399: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
5400: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
5401: remotePointsNew[m].rank = rrank;
5402: }
5403: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r;
5404: 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 + r;
5405: remotePointsNew[m].rank = rrank;
5406: ++m;
5407: } else if ((p >= cMax) && (p < cEnd)) {
5408: /* Hybrid cells add new cells and faces */
5409: for (r = 0; r < 4; ++r, ++m) {
5410: localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
5411: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
5412: remotePointsNew[m].rank = rrank;
5413: }
5414: for (r = 0; r < 3; ++r, ++m) {
5415: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
5416: 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;
5417: remotePointsNew[m].rank = rrank;
5418: }
5419: }
5420: break;
5421: case 6:
5422: /* Hex 3D */
5423: if ((p >= vStart) && (p < vEnd)) {
5424: /* Old vertices stay the same */
5425: localPointsNew[m] = vStartNew + (p - vStart);
5426: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5427: remotePointsNew[m].rank = rrank;
5428: ++m;
5429: } else if ((p >= eStart) && (p < eEnd)) {
5430: /* Old edges add new edges and vertex */
5431: for (r = 0; r < 2; ++r, ++m) {
5432: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
5433: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
5434: remotePointsNew[m].rank = rrank;
5435: }
5436: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
5437: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
5438: remotePointsNew[m].rank = rrank;
5439: ++m;
5440: } else if ((p >= fStart) && (p < fEnd)) {
5441: /* Old faces add new faces, edges, and vertex */
5442: for (r = 0; r < 4; ++r, ++m) {
5443: localPointsNew[m] = fStartNew + (p - fStart)*4 + r;
5444: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
5445: remotePointsNew[m].rank = rrank;
5446: }
5447: for (r = 0; r < 4; ++r, ++m) {
5448: localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
5449: remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r;
5450: remotePointsNew[m].rank = rrank;
5451: }
5452: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
5453: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
5454: remotePointsNew[m].rank = rrank;
5455: ++m;
5456: } else if ((p >= cStart) && (p < cEnd)) {
5457: /* Old cells add new cells, faces, edges, and vertex */
5458: for (r = 0; r < 8; ++r, ++m) {
5459: localPointsNew[m] = cStartNew + (p - cStart)*8 + r;
5460: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
5461: remotePointsNew[m].rank = rrank;
5462: }
5463: for (r = 0; r < 12; ++r, ++m) {
5464: localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
5465: remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r;
5466: remotePointsNew[m].rank = rrank;
5467: }
5468: for (r = 0; r < 6; ++r, ++m) {
5469: localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
5470: remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r;
5471: remotePointsNew[m].rank = rrank;
5472: }
5473: for (r = 0; r < 1; ++r, ++m) {
5474: localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r;
5475: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
5476: remotePointsNew[m].rank = rrank;
5477: }
5478: }
5479: break;
5480: case 8:
5481: /* Hybrid Hex 3D */
5482: if ((p >= vStart) && (p < vEnd)) {
5483: /* Interior vertices stay the same */
5484: localPointsNew[m] = vStartNew + (p - vStart);
5485: remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5486: remotePointsNew[m].rank = rrank;
5487: ++m;
5488: } else if ((p >= eStart) && (p < eMax)) {
5489: /* Interior edges add new edges and vertex */
5490: for (r = 0; r < 2; ++r, ++m) {
5491: localPointsNew[m] = eStartNew + (p - eStart)*2 + r;
5492: remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
5493: remotePointsNew[m].rank = rrank;
5494: }
5495: localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart);
5496: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
5497: remotePointsNew[m].rank = rrank;
5498: ++m;
5499: } else if ((p >= eMax) && (p < eEnd)) {
5500: /* Hybrid edges stay the same */
5501: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
5502: remotePointsNew[m].index = rvStartNew[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]);
5503: remotePointsNew[m].rank = rrank;
5504: ++m;
5505: } else if ((p >= fStart) && (p < fMax)) {
5506: /* Interior faces add new faces, edges, and vertex */
5507: for (r = 0; r < 4; ++r, ++m) {
5508: localPointsNew[m] = fStartNew + (p - fStart)*4 + r;
5509: remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
5510: remotePointsNew[m].rank = rrank;
5511: }
5512: for (r = 0; r < 4; ++r, ++m) {
5513: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
5514: remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
5515: remotePointsNew[m].rank = rrank;
5516: }
5517: localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
5518: remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
5519: remotePointsNew[m].rank = rrank;
5520: ++m;
5521: } else if ((p >= fMax) && (p < fEnd)) {
5522: /* Hybrid faces add new faces and edges */
5523: for (r = 0; r < 2; ++r, ++m) {
5524: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
5525: 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;
5526: remotePointsNew[m].rank = rrank;
5527: }
5528: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax);
5529: 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)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]);
5530: remotePointsNew[m].rank = rrank;
5531: ++m;
5532: } else if ((p >= cStart) && (p < cMax)) {
5533: /* Interior cells add new cells, faces, edges, and vertex */
5534: for (r = 0; r < 8; ++r, ++m) {
5535: localPointsNew[m] = cStartNew + (p - cStart)*8 + r;
5536: remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
5537: remotePointsNew[m].rank = rrank;
5538: }
5539: for (r = 0; r < 12; ++r, ++m) {
5540: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
5541: remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
5542: remotePointsNew[m].rank = rrank;
5543: }
5544: for (r = 0; r < 6; ++r, ++m) {
5545: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
5546: 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;
5547: remotePointsNew[m].rank = rrank;
5548: }
5549: for (r = 0; r < 1; ++r, ++m) {
5550: localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r;
5551: remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r;
5552: remotePointsNew[m].rank = rrank;
5553: }
5554: } else if ((p >= cMax) && (p < cEnd)) {
5555: /* Hybrid cells add new cells, faces, and edges */
5556: for (r = 0; r < 4; ++r, ++m) {
5557: localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
5558: remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
5559: remotePointsNew[m].rank = rrank;
5560: }
5561: for (r = 0; r < 4; ++r, ++m) {
5562: localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
5563: 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])*4 + r;
5564: remotePointsNew[m].rank = rrank;
5565: }
5566: localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
5567: 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)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]);
5568: remotePointsNew[m].rank = rrank;
5569: ++m;
5570: }
5571: break;
5572: default:
5573: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
5574: }
5575: }
5576: if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
5577: ISRestoreIndices(processRanks, &neighbors);
5578: ISDestroy(&processRanks);
5579: PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);
5580: PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);
5581: PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);
5582: return(0);
5583: }
5587: static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
5588: {
5589: PetscInt numLabels, l;
5590: PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
5591: PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
5595: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
5596: DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);
5597: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
5598: DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);
5599: DMPlexGetDepth(dm, &depth);
5600: if (refiner) {GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);}
5601: DMPlexGetNumLabels(dm, &numLabels);
5602: DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);
5603: switch (refiner) {
5604: case 0: break;
5605: case 7:
5606: case 8:
5607: if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
5608: case 3:
5609: case 4:
5610: if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
5611: if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
5612: }
5613: for (l = 0; l < numLabels; ++l) {
5614: DMLabel label, labelNew;
5615: const char *lname;
5616: PetscBool isDepth;
5617: IS valueIS;
5618: const PetscInt *values;
5619: PetscInt numValues, val;
5621: DMPlexGetLabelName(dm, l, &lname);
5622: PetscStrcmp(lname, "depth", &isDepth);
5623: if (isDepth) continue;
5624: DMPlexCreateLabel(rdm, lname);
5625: DMPlexGetLabel(dm, lname, &label);
5626: DMPlexGetLabel(rdm, lname, &labelNew);
5627: DMLabelGetValueIS(label, &valueIS);
5628: ISGetLocalSize(valueIS, &numValues);
5629: ISGetIndices(valueIS, &values);
5630: for (val = 0; val < numValues; ++val) {
5631: IS pointIS;
5632: const PetscInt *points;
5633: PetscInt numPoints, n;
5635: DMLabelGetStratumIS(label, values[val], &pointIS);
5636: ISGetLocalSize(pointIS, &numPoints);
5637: ISGetIndices(pointIS, &points);
5638: for (n = 0; n < numPoints; ++n) {
5639: const PetscInt p = points[n];
5640: switch (refiner) {
5641: case 1:
5642: /* Simplicial 2D */
5643: if ((p >= vStart) && (p < vEnd)) {
5644: /* Old vertices stay the same */
5645: newp = vStartNew + (p - vStart);
5646: DMLabelSetValue(labelNew, newp, values[val]);
5647: } else if ((p >= fStart) && (p < fEnd)) {
5648: /* Old faces add new faces and vertex */
5649: newp = vStartNew + (vEnd - vStart) + (p - fStart);
5650: DMLabelSetValue(labelNew, newp, values[val]);
5651: for (r = 0; r < 2; ++r) {
5652: newp = fStartNew + (p - fStart)*2 + r;
5653: DMLabelSetValue(labelNew, newp, values[val]);
5654: }
5655: } else if ((p >= cStart) && (p < cEnd)) {
5656: /* Old cells add new cells and interior faces */
5657: for (r = 0; r < 4; ++r) {
5658: newp = cStartNew + (p - cStart)*4 + r;
5659: DMLabelSetValue(labelNew, newp, values[val]);
5660: }
5661: for (r = 0; r < 3; ++r) {
5662: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
5663: DMLabelSetValue(labelNew, newp, values[val]);
5664: }
5665: }
5666: break;
5667: case 2:
5668: /* Hex 2D */
5669: if ((p >= vStart) && (p < vEnd)) {
5670: /* Old vertices stay the same */
5671: newp = vStartNew + (p - vStart);
5672: DMLabelSetValue(labelNew, newp, values[val]);
5673: } else if ((p >= fStart) && (p < fEnd)) {
5674: /* Old faces add new faces and vertex */
5675: newp = vStartNew + (vEnd - vStart) + (p - fStart);
5676: DMLabelSetValue(labelNew, newp, values[val]);
5677: for (r = 0; r < 2; ++r) {
5678: newp = fStartNew + (p - fStart)*2 + r;
5679: DMLabelSetValue(labelNew, newp, values[val]);
5680: }
5681: } else if ((p >= cStart) && (p < cEnd)) {
5682: /* Old cells add new cells and interior faces and vertex */
5683: for (r = 0; r < 4; ++r) {
5684: newp = cStartNew + (p - cStart)*4 + r;
5685: DMLabelSetValue(labelNew, newp, values[val]);
5686: }
5687: for (r = 0; r < 4; ++r) {
5688: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
5689: DMLabelSetValue(labelNew, newp, values[val]);
5690: }
5691: newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
5692: DMLabelSetValue(labelNew, newp, values[val]);
5693: }
5694: break;
5695: case 3:
5696: /* Hybrid simplicial 2D */
5697: if ((p >= vStart) && (p < vEnd)) {
5698: /* Old vertices stay the same */
5699: newp = vStartNew + (p - vStart);
5700: DMLabelSetValue(labelNew, newp, values[val]);
5701: } else if ((p >= fStart) && (p < fMax)) {
5702: /* Old interior faces add new faces and vertex */
5703: newp = vStartNew + (vEnd - vStart) + (p - fStart);
5704: DMLabelSetValue(labelNew, newp, values[val]);
5705: for (r = 0; r < 2; ++r) {
5706: newp = fStartNew + (p - fStart)*2 + r;
5707: DMLabelSetValue(labelNew, newp, values[val]);
5708: }
5709: } else if ((p >= fMax) && (p < fEnd)) {
5710: /* Old hybrid faces stay the same */
5711: newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
5712: DMLabelSetValue(labelNew, newp, values[val]);
5713: } else if ((p >= cStart) && (p < cMax)) {
5714: /* Old interior cells add new cells and interior faces */
5715: for (r = 0; r < 4; ++r) {
5716: newp = cStartNew + (p - cStart)*4 + r;
5717: DMLabelSetValue(labelNew, newp, values[val]);
5718: }
5719: for (r = 0; r < 3; ++r) {
5720: newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
5721: DMLabelSetValue(labelNew, newp, values[val]);
5722: }
5723: } else if ((p >= cMax) && (p < cEnd)) {
5724: /* Old hybrid cells add new cells and hybrid face */
5725: for (r = 0; r < 2; ++r) {
5726: newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
5727: DMLabelSetValue(labelNew, newp, values[val]);
5728: }
5729: newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
5730: DMLabelSetValue(labelNew, newp, values[val]);
5731: }
5732: break;
5733: case 5:
5734: /* Simplicial 3D */
5735: if ((p >= vStart) && (p < vEnd)) {
5736: /* Old vertices stay the same */
5737: newp = vStartNew + (p - vStart);
5738: DMLabelSetValue(labelNew, newp, values[val]);
5739: } else if ((p >= eStart) && (p < eEnd)) {
5740: /* Old edges add new edges and vertex */
5741: for (r = 0; r < 2; ++r) {
5742: newp = eStartNew + (p - eStart)*2 + r;
5743: DMLabelSetValue(labelNew, newp, values[val]);
5744: }
5745: newp = vStartNew + (vEnd - vStart) + (p - eStart);
5746: DMLabelSetValue(labelNew, newp, values[val]);
5747: } else if ((p >= fStart) && (p < fEnd)) {
5748: /* Old faces add new faces and edges */
5749: for (r = 0; r < 4; ++r) {
5750: newp = fStartNew + (p - fStart)*4 + r;
5751: DMLabelSetValue(labelNew, newp, values[val]);
5752: }
5753: for (r = 0; r < 3; ++r) {
5754: newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
5755: DMLabelSetValue(labelNew, newp, values[val]);
5756: }
5757: } else if ((p >= cStart) && (p < cEnd)) {
5758: /* Old cells add new cells and interior faces and edges */
5759: for (r = 0; r < 8; ++r) {
5760: newp = cStartNew + (p - cStart)*8 + r;
5761: DMLabelSetValue(labelNew, newp, values[val]);
5762: }
5763: for (r = 0; r < 8; ++r) {
5764: newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
5765: DMLabelSetValue(labelNew, newp, values[val]);
5766: }
5767: for (r = 0; r < 1; ++r) {
5768: newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
5769: DMLabelSetValue(labelNew, newp, values[val]);
5770: }
5771: }
5772: break;
5773: case 7:
5774: /* Hybrid Simplicial 3D */
5775: if ((p >= vStart) && (p < vEnd)) {
5776: /* Interior vertices stay the same */
5777: newp = vStartNew + (p - vStart);
5778: DMLabelSetValue(labelNew, newp, values[val]);
5779: } else if ((p >= eStart) && (p < eMax)) {
5780: /* Interior edges add new edges and vertex */
5781: for (r = 0; r < 2; ++r) {
5782: newp = eStartNew + (p - eStart)*2 + r;
5783: DMLabelSetValue(labelNew, newp, values[val]);
5784: }
5785: newp = vStartNew + (vEnd - vStart) + (p - eStart);
5786: DMLabelSetValue(labelNew, newp, values[val]);
5787: } else if ((p >= eMax) && (p < eEnd)) {
5788: /* Hybrid edges stay the same */
5789: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
5790: DMLabelSetValue(labelNew, newp, values[val]);
5791: } else if ((p >= fStart) && (p < fMax)) {
5792: /* Interior faces add new faces and edges */
5793: for (r = 0; r < 4; ++r) {
5794: newp = fStartNew + (p - fStart)*4 + r;
5795: DMLabelSetValue(labelNew, newp, values[val]);
5796: }
5797: for (r = 0; r < 3; ++r) {
5798: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
5799: DMLabelSetValue(labelNew, newp, values[val]);
5800: }
5801: } else if ((p >= fMax) && (p < fEnd)) {
5802: /* Hybrid faces add new faces and edges */
5803: for (r = 0; r < 2; ++r) {
5804: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
5805: DMLabelSetValue(labelNew, newp, values[val]);
5806: }
5807: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
5808: DMLabelSetValue(labelNew, newp, values[val]);
5809: } else if ((p >= cStart) && (p < cMax)) {
5810: /* Interior cells add new cells, faces, and edges */
5811: for (r = 0; r < 8; ++r) {
5812: newp = cStartNew + (p - cStart)*8 + r;
5813: DMLabelSetValue(labelNew, newp, values[val]);
5814: }
5815: for (r = 0; r < 8; ++r) {
5816: newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
5817: DMLabelSetValue(labelNew, newp, values[val]);
5818: }
5819: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
5820: DMLabelSetValue(labelNew, newp, values[val]);
5821: } else if ((p >= cMax) && (p < cEnd)) {
5822: /* Hybrid cells add new cells and faces */
5823: for (r = 0; r < 4; ++r) {
5824: newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
5825: DMLabelSetValue(labelNew, newp, values[val]);
5826: }
5827: for (r = 0; r < 3; ++r) {
5828: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
5829: DMLabelSetValue(labelNew, newp, values[val]);
5830: }
5831: }
5832: break;
5833: case 6:
5834: /* Hex 3D */
5835: if ((p >= vStart) && (p < vEnd)) {
5836: /* Old vertices stay the same */
5837: newp = vStartNew + (p - vStart);
5838: DMLabelSetValue(labelNew, newp, values[val]);
5839: } else if ((p >= eStart) && (p < eEnd)) {
5840: /* Old edges add new edges and vertex */
5841: for (r = 0; r < 2; ++r) {
5842: newp = eStartNew + (p - eStart)*2 + r;
5843: DMLabelSetValue(labelNew, newp, values[val]);
5844: }
5845: newp = vStartNew + (vEnd - vStart) + (p - eStart);
5846: DMLabelSetValue(labelNew, newp, values[val]);
5847: } else if ((p >= fStart) && (p < fEnd)) {
5848: /* Old faces add new faces, edges, and vertex */
5849: for (r = 0; r < 4; ++r) {
5850: newp = fStartNew + (p - fStart)*4 + r;
5851: DMLabelSetValue(labelNew, newp, values[val]);
5852: }
5853: for (r = 0; r < 4; ++r) {
5854: newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
5855: DMLabelSetValue(labelNew, newp, values[val]);
5856: }
5857: newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
5858: DMLabelSetValue(labelNew, newp, values[val]);
5859: } else if ((p >= cStart) && (p < cEnd)) {
5860: /* Old cells add new cells, faces, edges, and vertex */
5861: for (r = 0; r < 8; ++r) {
5862: newp = cStartNew + (p - cStart)*8 + r;
5863: DMLabelSetValue(labelNew, newp, values[val]);
5864: }
5865: for (r = 0; r < 12; ++r) {
5866: newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
5867: DMLabelSetValue(labelNew, newp, values[val]);
5868: }
5869: for (r = 0; r < 6; ++r) {
5870: newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
5871: DMLabelSetValue(labelNew, newp, values[val]);
5872: }
5873: newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
5874: DMLabelSetValue(labelNew, newp, values[val]);
5875: }
5876: break;
5877: case 8:
5878: /* Hybrid Hex 3D */
5879: if ((p >= vStart) && (p < vEnd)) {
5880: /* Interior vertices stay the same */
5881: newp = vStartNew + (p - vStart);
5882: DMLabelSetValue(labelNew, newp, values[val]);
5883: } else if ((p >= eStart) && (p < eMax)) {
5884: /* Interior edges add new edges and vertex */
5885: for (r = 0; r < 2; ++r) {
5886: newp = eStartNew + (p - eStart)*2 + r;
5887: DMLabelSetValue(labelNew, newp, values[val]);
5888: }
5889: newp = vStartNew + (vEnd - vStart) + (p - eStart);
5890: DMLabelSetValue(labelNew, newp, values[val]);
5891: } else if ((p >= eMax) && (p < eEnd)) {
5892: /* Hybrid edges stay the same */
5893: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
5894: DMLabelSetValue(labelNew, newp, values[val]);
5895: } else if ((p >= fStart) && (p < fMax)) {
5896: /* Interior faces add new faces, edges, and vertex */
5897: for (r = 0; r < 4; ++r) {
5898: newp = fStartNew + (p - fStart)*4 + r;
5899: DMLabelSetValue(labelNew, newp, values[val]);
5900: }
5901: for (r = 0; r < 4; ++r) {
5902: newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
5903: DMLabelSetValue(labelNew, newp, values[val]);
5904: }
5905: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
5906: DMLabelSetValue(labelNew, newp, values[val]);
5907: } else if ((p >= fMax) && (p < fEnd)) {
5908: /* Hybrid faces add new faces and edges */
5909: for (r = 0; r < 2; ++r) {
5910: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
5911: DMLabelSetValue(labelNew, newp, values[val]);
5912: }
5913: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
5914: DMLabelSetValue(labelNew, newp, values[val]);
5915: } else if ((p >= cStart) && (p < cMax)) {
5916: /* Interior cells add new cells, faces, edges, and vertex */
5917: for (r = 0; r < 8; ++r) {
5918: newp = cStartNew + (p - cStart)*8 + r;
5919: DMLabelSetValue(labelNew, newp, values[val]);
5920: }
5921: for (r = 0; r < 12; ++r) {
5922: newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
5923: DMLabelSetValue(labelNew, newp, values[val]);
5924: }
5925: for (r = 0; r < 6; ++r) {
5926: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
5927: DMLabelSetValue(labelNew, newp, values[val]);
5928: }
5929: newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
5930: DMLabelSetValue(labelNew, newp, values[val]);
5931: } else if ((p >= cMax) && (p < cEnd)) {
5932: /* Hybrid cells add new cells, faces, and edges */
5933: for (r = 0; r < 4; ++r) {
5934: newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
5935: DMLabelSetValue(labelNew, newp, values[val]);
5936: }
5937: for (r = 0; r < 4; ++r) {
5938: newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
5939: DMLabelSetValue(labelNew, newp, values[val]);
5940: }
5941: newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
5942: DMLabelSetValue(labelNew, newp, values[val]);
5943: }
5944: break;
5945: default:
5946: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
5947: }
5948: }
5949: ISRestoreIndices(pointIS, &points);
5950: ISDestroy(&pointIS);
5951: }
5952: ISRestoreIndices(valueIS, &values);
5953: ISDestroy(&valueIS);
5954: if (0) {
5955: PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);
5956: DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);
5957: PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);
5958: }
5959: }
5960: return(0);
5961: }
5965: /* This will only work for interpolated meshes */
5966: PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
5967: {
5968: DM rdm;
5969: PetscInt *depthSize;
5970: PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0;
5974: DMCreate(PetscObjectComm((PetscObject)dm), &rdm);
5975: DMSetType(rdm, DMPLEX);
5976: DMPlexGetDimension(dm, &dim);
5977: DMPlexSetDimension(rdm, dim);
5978: /* Calculate number of new points of each depth */
5979: DMPlexGetDepth(dm, &depth);
5980: PetscMalloc1((depth+1), &depthSize);
5981: PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));
5982: CellRefinerGetSizes(cellRefiner, dm, depthSize);
5983: /* Step 1: Set chart */
5984: for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
5985: DMPlexSetChart(rdm, pStart, pEnd);
5986: /* Step 2: Set cone/support sizes */
5987: CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);
5988: /* Step 3: Setup refined DM */
5989: DMSetUp(rdm);
5990: /* Step 4: Set cones and supports */
5991: CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);
5992: /* Step 5: Stratify */
5993: DMPlexStratify(rdm);
5994: /* Step 6: Set coordinates for vertices */
5995: CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);
5996: /* Step 7: Create pointSF */
5997: CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);
5998: /* Step 8: Create labels */
5999: CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);
6000: PetscFree(depthSize);
6002: *dmRefined = rdm;
6003: return(0);
6004: }
6008: PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
6009: {
6010: DM_Plex *mesh = (DM_Plex*) dm->data;
6014: mesh->refinementUniform = refinementUniform;
6015: return(0);
6016: }
6020: PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
6021: {
6022: DM_Plex *mesh = (DM_Plex*) dm->data;
6027: *refinementUniform = mesh->refinementUniform;
6028: return(0);
6029: }
6033: PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
6034: {
6035: DM_Plex *mesh = (DM_Plex*) dm->data;
6039: mesh->refinementLimit = refinementLimit;
6040: return(0);
6041: }
6045: PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
6046: {
6047: DM_Plex *mesh = (DM_Plex*) dm->data;
6052: /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
6053: *refinementLimit = mesh->refinementLimit;
6054: return(0);
6055: }
6059: PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
6060: {
6061: PetscInt dim, cStart, cEnd, coneSize, cMax;
6065: DMPlexGetDimension(dm, &dim);
6066: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
6067: if (cEnd <= cStart) {*cellRefiner = 0; return(0);}
6068: DMPlexGetConeSize(dm, cStart, &coneSize);
6069: DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);
6070: switch (dim) {
6071: case 2:
6072: switch (coneSize) {
6073: case 3:
6074: if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
6075: else *cellRefiner = 1; /* Triangular */
6076: break;
6077: case 4:
6078: if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
6079: else *cellRefiner = 2; /* Quadrilateral */
6080: break;
6081: default:
6082: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
6083: }
6084: break;
6085: case 3:
6086: switch (coneSize) {
6087: case 4:
6088: if (cMax >= 0) *cellRefiner = 7; /* Hybrid */
6089: else *cellRefiner = 5; /* Tetrahedral */
6090: break;
6091: case 6:
6092: if (cMax >= 0) *cellRefiner = 8; /* Hybrid */
6093: else *cellRefiner = 6; /* hexahedral */
6094: break;
6095: default:
6096: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
6097: }
6098: break;
6099: default:
6100: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
6101: }
6102: return(0);
6103: }