1 #include <petsc/private/dmplextransformimpl.h> /*I "petscdmplextransform.h" I*/
2
3 /*
4 When using the active label, refine types are as follows:
5
6 Two types are allocated for
7 DM_POLYTOPE_POINT_PRISM_TENSOR
8 DM_POLYTOPE_SEG_PRISM_TENSOR
9 DM_POLYTOPE_TRI_PRISM_TENSOR
10 DM_POLYTOPE_QUAD_PRISM_TENSOR
11 the first is identity, and the second refines.
12 All other types are identity. All the refine types are numbered in order.
13 */
DMPlexTransformSetUp_BL(DMPlexTransform tr)14 static PetscErrorCode DMPlexTransformSetUp_BL(DMPlexTransform tr)
15 {
16 DMPlexRefine_BL *bl = (DMPlexRefine_BL *)tr->data;
17 const PetscInt n = bl->n;
18 DMPolytopeType ct;
19 DM dm;
20 DMLabel active;
21 PetscInt Nc, No, coff, i, ict;
22
23 PetscFunctionBegin;
24 /* If no label is given, split all tensor cells */
25 PetscCall(DMPlexTransformGetDM(tr, &dm));
26 PetscCall(DMPlexTransformGetActive(tr, &active));
27 if (active) {
28 IS refineIS;
29 const PetscInt *refineCells;
30 PetscInt pStart, pEnd, p, c;
31
32 PetscCall(DMLabelCreate(PETSC_COMM_SELF, "Refine Type", &tr->trType));
33 PetscCall(DMLabelGetStratumIS(active, DM_ADAPT_REFINE, &refineIS));
34 PetscCall(DMLabelGetStratumSize(active, DM_ADAPT_REFINE, &Nc));
35 if (refineIS) PetscCall(ISGetIndices(refineIS, &refineCells));
36 for (c = 0; c < Nc; ++c) {
37 const PetscInt cell = refineCells[c];
38 PetscInt *closure = NULL;
39 PetscInt Ncl, cl;
40
41 PetscCall(DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &Ncl, &closure));
42 for (cl = 0; cl < Ncl * 2; cl += 2) {
43 const PetscInt point = closure[cl];
44 PetscInt val;
45
46 PetscCall(DMPlexGetCellType(dm, point, &ct));
47 val = (PetscInt)ct;
48 if (ct > DM_POLYTOPE_POINT_PRISM_TENSOR) ++val;
49 if (ct > DM_POLYTOPE_SEG_PRISM_TENSOR) ++val;
50 if (ct > DM_POLYTOPE_TRI_PRISM_TENSOR) ++val;
51 if (ct > DM_POLYTOPE_QUAD_PRISM_TENSOR) ++val;
52 switch (ct) {
53 case DM_POLYTOPE_POINT_PRISM_TENSOR:
54 case DM_POLYTOPE_SEG_PRISM_TENSOR:
55 case DM_POLYTOPE_TRI_PRISM_TENSOR:
56 case DM_POLYTOPE_QUAD_PRISM_TENSOR:
57 PetscCall(DMLabelSetValue(tr->trType, point, val + 1));
58 break;
59 default:
60 break;
61 }
62 }
63 PetscCall(DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &Ncl, &closure));
64 }
65 if (refineIS) PetscCall(ISRestoreIndices(refineIS, &refineCells));
66 PetscCall(ISDestroy(&refineIS));
67 PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
68 for (p = pStart; p < pEnd; ++p) {
69 PetscInt val;
70
71 PetscCall(DMLabelGetValue(tr->trType, p, &val));
72 if (val < 0) {
73 PetscCall(DMPlexGetCellType(dm, p, &ct));
74 val = (PetscInt)ct;
75 if (ct > DM_POLYTOPE_POINT_PRISM_TENSOR) ++val;
76 if (ct > DM_POLYTOPE_SEG_PRISM_TENSOR) ++val;
77 if (ct > DM_POLYTOPE_TRI_PRISM_TENSOR) ++val;
78 if (ct > DM_POLYTOPE_QUAD_PRISM_TENSOR) ++val;
79 PetscCall(DMLabelSetValue(tr->trType, p, val));
80 }
81 }
82 }
83 /* Cell heights */
84 PetscCall(PetscMalloc1(n, &bl->h));
85 if (bl->r > 1.) {
86 /* initial height h_0 = (r - 1) / (r^{n+1} - 1)
87 cell height h_i = r^i h_0
88 so that \sum^n_{i = 0} h_i = h_0 \sum^n_{i=0} r^i = h_0 (r^{n+1} - 1) / (r - 1) = 1
89 */
90 PetscReal d = (bl->r - 1.) / (PetscPowRealInt(bl->r, n + 1) - 1.);
91
92 bl->h[0] = d;
93 for (i = 1; i < n; ++i) {
94 d *= bl->r;
95 bl->h[i] = bl->h[i - 1] + d;
96 }
97 } else {
98 /* equal division */
99 for (i = 0; i < n; ++i) bl->h[i] = (i + 1.) / (n + 1);
100 }
101
102 PetscCall(PetscMalloc5(DM_NUM_POLYTOPES, &bl->Nt, DM_NUM_POLYTOPES, &bl->target, DM_NUM_POLYTOPES, &bl->size, DM_NUM_POLYTOPES, &bl->cone, DM_NUM_POLYTOPES, &bl->ornt));
103 for (ict = 0; ict < DM_NUM_POLYTOPES; ++ict) {
104 bl->Nt[ict] = -1;
105 bl->target[ict] = NULL;
106 bl->size[ict] = NULL;
107 bl->cone[ict] = NULL;
108 bl->ornt[ict] = NULL;
109 }
110 /* DM_POLYTOPE_POINT_PRISM_TENSOR produces n points and n+1 tensor segments */
111 ct = DM_POLYTOPE_POINT_PRISM_TENSOR;
112 bl->Nt[ct] = 2;
113 Nc = 7 * 2 + 6 * (n - 1);
114 No = 2 * (n + 1);
115 PetscCall(PetscMalloc4(bl->Nt[ct], &bl->target[ct], bl->Nt[ct], &bl->size[ct], Nc, &bl->cone[ct], No, &bl->ornt[ct]));
116 bl->target[ct][0] = DM_POLYTOPE_POINT;
117 bl->target[ct][1] = DM_POLYTOPE_POINT_PRISM_TENSOR;
118 bl->size[ct][0] = n;
119 bl->size[ct][1] = n + 1;
120 /* cones for tensor segments */
121 bl->cone[ct][0] = DM_POLYTOPE_POINT;
122 bl->cone[ct][1] = 1;
123 bl->cone[ct][2] = 0;
124 bl->cone[ct][3] = 0;
125 bl->cone[ct][4] = DM_POLYTOPE_POINT;
126 bl->cone[ct][5] = 0;
127 bl->cone[ct][6] = 0;
128 for (i = 0; i < n - 1; ++i) {
129 bl->cone[ct][7 + 6 * i + 0] = DM_POLYTOPE_POINT;
130 bl->cone[ct][7 + 6 * i + 1] = 0;
131 bl->cone[ct][7 + 6 * i + 2] = i;
132 bl->cone[ct][7 + 6 * i + 3] = DM_POLYTOPE_POINT;
133 bl->cone[ct][7 + 6 * i + 4] = 0;
134 bl->cone[ct][7 + 6 * i + 5] = i + 1;
135 }
136 bl->cone[ct][7 + 6 * (n - 1) + 0] = DM_POLYTOPE_POINT;
137 bl->cone[ct][7 + 6 * (n - 1) + 1] = 0;
138 bl->cone[ct][7 + 6 * (n - 1) + 2] = n - 1;
139 bl->cone[ct][7 + 6 * (n - 1) + 3] = DM_POLYTOPE_POINT;
140 bl->cone[ct][7 + 6 * (n - 1) + 4] = 1;
141 bl->cone[ct][7 + 6 * (n - 1) + 5] = 1;
142 bl->cone[ct][7 + 6 * (n - 1) + 6] = 0;
143 for (i = 0; i < No; i++) bl->ornt[ct][i] = 0;
144 /* DM_POLYTOPE_SEG_PRISM_TENSOR produces n segments and n+1 tensor quads */
145 ct = DM_POLYTOPE_SEG_PRISM_TENSOR;
146 bl->Nt[ct] = 2;
147 Nc = 8 * n + 15 * 2 + 14 * (n - 1);
148 No = 2 * n + 4 * (n + 1);
149 PetscCall(PetscMalloc4(bl->Nt[ct], &bl->target[ct], bl->Nt[ct], &bl->size[ct], Nc, &bl->cone[ct], No, &bl->ornt[ct]));
150 bl->target[ct][0] = DM_POLYTOPE_SEGMENT;
151 bl->target[ct][1] = DM_POLYTOPE_SEG_PRISM_TENSOR;
152 bl->size[ct][0] = n;
153 bl->size[ct][1] = n + 1;
154 /* cones for segments */
155 for (i = 0; i < n; ++i) {
156 bl->cone[ct][8 * i + 0] = DM_POLYTOPE_POINT;
157 bl->cone[ct][8 * i + 1] = 1;
158 bl->cone[ct][8 * i + 2] = 2;
159 bl->cone[ct][8 * i + 3] = i;
160 bl->cone[ct][8 * i + 4] = DM_POLYTOPE_POINT;
161 bl->cone[ct][8 * i + 5] = 1;
162 bl->cone[ct][8 * i + 6] = 3;
163 bl->cone[ct][8 * i + 7] = i;
164 }
165 /* cones for tensor quads */
166 coff = 8 * n;
167 bl->cone[ct][coff + 0] = DM_POLYTOPE_SEGMENT;
168 bl->cone[ct][coff + 1] = 1;
169 bl->cone[ct][coff + 2] = 0;
170 bl->cone[ct][coff + 3] = 0;
171 bl->cone[ct][coff + 4] = DM_POLYTOPE_SEGMENT;
172 bl->cone[ct][coff + 5] = 0;
173 bl->cone[ct][coff + 6] = 0;
174 bl->cone[ct][coff + 7] = DM_POLYTOPE_POINT_PRISM_TENSOR;
175 bl->cone[ct][coff + 8] = 1;
176 bl->cone[ct][coff + 9] = 2;
177 bl->cone[ct][coff + 10] = 0;
178 bl->cone[ct][coff + 11] = DM_POLYTOPE_POINT_PRISM_TENSOR;
179 bl->cone[ct][coff + 12] = 1;
180 bl->cone[ct][coff + 13] = 3;
181 bl->cone[ct][coff + 14] = 0;
182 for (i = 0; i < n - 1; ++i) {
183 bl->cone[ct][coff + 15 + 14 * i + 0] = DM_POLYTOPE_SEGMENT;
184 bl->cone[ct][coff + 15 + 14 * i + 1] = 0;
185 bl->cone[ct][coff + 15 + 14 * i + 2] = i;
186 bl->cone[ct][coff + 15 + 14 * i + 3] = DM_POLYTOPE_SEGMENT;
187 bl->cone[ct][coff + 15 + 14 * i + 4] = 0;
188 bl->cone[ct][coff + 15 + 14 * i + 5] = i + 1;
189 bl->cone[ct][coff + 15 + 14 * i + 6] = DM_POLYTOPE_POINT_PRISM_TENSOR;
190 bl->cone[ct][coff + 15 + 14 * i + 7] = 1;
191 bl->cone[ct][coff + 15 + 14 * i + 8] = 2;
192 bl->cone[ct][coff + 15 + 14 * i + 9] = i + 1;
193 bl->cone[ct][coff + 15 + 14 * i + 10] = DM_POLYTOPE_POINT_PRISM_TENSOR;
194 bl->cone[ct][coff + 15 + 14 * i + 11] = 1;
195 bl->cone[ct][coff + 15 + 14 * i + 12] = 3;
196 bl->cone[ct][coff + 15 + 14 * i + 13] = i + 1;
197 }
198 bl->cone[ct][coff + 15 + 14 * (n - 1) + 0] = DM_POLYTOPE_SEGMENT;
199 bl->cone[ct][coff + 15 + 14 * (n - 1) + 1] = 0;
200 bl->cone[ct][coff + 15 + 14 * (n - 1) + 2] = n - 1;
201 bl->cone[ct][coff + 15 + 14 * (n - 1) + 3] = DM_POLYTOPE_SEGMENT;
202 bl->cone[ct][coff + 15 + 14 * (n - 1) + 4] = 1;
203 bl->cone[ct][coff + 15 + 14 * (n - 1) + 5] = 1;
204 bl->cone[ct][coff + 15 + 14 * (n - 1) + 6] = 0;
205 bl->cone[ct][coff + 15 + 14 * (n - 1) + 7] = DM_POLYTOPE_POINT_PRISM_TENSOR;
206 bl->cone[ct][coff + 15 + 14 * (n - 1) + 8] = 1;
207 bl->cone[ct][coff + 15 + 14 * (n - 1) + 9] = 2;
208 bl->cone[ct][coff + 15 + 14 * (n - 1) + 10] = n;
209 bl->cone[ct][coff + 15 + 14 * (n - 1) + 11] = DM_POLYTOPE_POINT_PRISM_TENSOR;
210 bl->cone[ct][coff + 15 + 14 * (n - 1) + 12] = 1;
211 bl->cone[ct][coff + 15 + 14 * (n - 1) + 13] = 3;
212 bl->cone[ct][coff + 15 + 14 * (n - 1) + 14] = n;
213 for (i = 0; i < No; i++) bl->ornt[ct][i] = 0;
214 /* DM_POLYTOPE_TRI_PRISM_TENSOR produces n triangles and n+1 tensor triangular prisms */
215 ct = DM_POLYTOPE_TRI_PRISM_TENSOR;
216 bl->Nt[ct] = 2;
217 Nc = 12 * n + 19 * 2 + 18 * (n - 1);
218 No = 3 * n + 5 * (n + 1);
219 PetscCall(PetscMalloc4(bl->Nt[ct], &bl->target[ct], bl->Nt[ct], &bl->size[ct], Nc, &bl->cone[ct], No, &bl->ornt[ct]));
220 bl->target[ct][0] = DM_POLYTOPE_TRIANGLE;
221 bl->target[ct][1] = DM_POLYTOPE_TRI_PRISM_TENSOR;
222 bl->size[ct][0] = n;
223 bl->size[ct][1] = n + 1;
224 /* cones for triangles */
225 for (i = 0; i < n; ++i) {
226 bl->cone[ct][12 * i + 0] = DM_POLYTOPE_SEGMENT;
227 bl->cone[ct][12 * i + 1] = 1;
228 bl->cone[ct][12 * i + 2] = 2;
229 bl->cone[ct][12 * i + 3] = i;
230 bl->cone[ct][12 * i + 4] = DM_POLYTOPE_SEGMENT;
231 bl->cone[ct][12 * i + 5] = 1;
232 bl->cone[ct][12 * i + 6] = 3;
233 bl->cone[ct][12 * i + 7] = i;
234 bl->cone[ct][12 * i + 8] = DM_POLYTOPE_SEGMENT;
235 bl->cone[ct][12 * i + 9] = 1;
236 bl->cone[ct][12 * i + 10] = 4;
237 bl->cone[ct][12 * i + 11] = i;
238 }
239 /* cones for triangular prisms */
240 coff = 12 * n;
241 bl->cone[ct][coff + 0] = DM_POLYTOPE_TRIANGLE;
242 bl->cone[ct][coff + 1] = 1;
243 bl->cone[ct][coff + 2] = 0;
244 bl->cone[ct][coff + 3] = 0;
245 bl->cone[ct][coff + 4] = DM_POLYTOPE_TRIANGLE;
246 bl->cone[ct][coff + 5] = 0;
247 bl->cone[ct][coff + 6] = 0;
248 bl->cone[ct][coff + 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
249 bl->cone[ct][coff + 8] = 1;
250 bl->cone[ct][coff + 9] = 2;
251 bl->cone[ct][coff + 10] = 0;
252 bl->cone[ct][coff + 11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
253 bl->cone[ct][coff + 12] = 1;
254 bl->cone[ct][coff + 13] = 3;
255 bl->cone[ct][coff + 14] = 0;
256 bl->cone[ct][coff + 15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
257 bl->cone[ct][coff + 16] = 1;
258 bl->cone[ct][coff + 17] = 4;
259 bl->cone[ct][coff + 18] = 0;
260 for (i = 0; i < n - 1; ++i) {
261 bl->cone[ct][coff + 19 + 18 * i + 0] = DM_POLYTOPE_TRIANGLE;
262 bl->cone[ct][coff + 19 + 18 * i + 1] = 0;
263 bl->cone[ct][coff + 19 + 18 * i + 2] = i;
264 bl->cone[ct][coff + 19 + 18 * i + 3] = DM_POLYTOPE_TRIANGLE;
265 bl->cone[ct][coff + 19 + 18 * i + 4] = 0;
266 bl->cone[ct][coff + 19 + 18 * i + 5] = i + 1;
267 bl->cone[ct][coff + 19 + 18 * i + 6] = DM_POLYTOPE_SEG_PRISM_TENSOR;
268 bl->cone[ct][coff + 19 + 18 * i + 7] = 1;
269 bl->cone[ct][coff + 19 + 18 * i + 8] = 2;
270 bl->cone[ct][coff + 19 + 18 * i + 9] = i + 1;
271 bl->cone[ct][coff + 19 + 18 * i + 10] = DM_POLYTOPE_SEG_PRISM_TENSOR;
272 bl->cone[ct][coff + 19 + 18 * i + 11] = 1;
273 bl->cone[ct][coff + 19 + 18 * i + 12] = 3;
274 bl->cone[ct][coff + 19 + 18 * i + 13] = i + 1;
275 bl->cone[ct][coff + 19 + 18 * i + 14] = DM_POLYTOPE_SEG_PRISM_TENSOR;
276 bl->cone[ct][coff + 19 + 18 * i + 15] = 1;
277 bl->cone[ct][coff + 19 + 18 * i + 16] = 4;
278 bl->cone[ct][coff + 19 + 18 * i + 17] = i + 1;
279 }
280 bl->cone[ct][coff + 19 + 18 * (n - 1) + 0] = DM_POLYTOPE_TRIANGLE;
281 bl->cone[ct][coff + 19 + 18 * (n - 1) + 1] = 0;
282 bl->cone[ct][coff + 19 + 18 * (n - 1) + 2] = n - 1;
283 bl->cone[ct][coff + 19 + 18 * (n - 1) + 3] = DM_POLYTOPE_TRIANGLE;
284 bl->cone[ct][coff + 19 + 18 * (n - 1) + 4] = 1;
285 bl->cone[ct][coff + 19 + 18 * (n - 1) + 5] = 1;
286 bl->cone[ct][coff + 19 + 18 * (n - 1) + 6] = 0;
287 bl->cone[ct][coff + 19 + 18 * (n - 1) + 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
288 bl->cone[ct][coff + 19 + 18 * (n - 1) + 8] = 1;
289 bl->cone[ct][coff + 19 + 18 * (n - 1) + 9] = 2;
290 bl->cone[ct][coff + 19 + 18 * (n - 1) + 10] = n;
291 bl->cone[ct][coff + 19 + 18 * (n - 1) + 11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
292 bl->cone[ct][coff + 19 + 18 * (n - 1) + 12] = 1;
293 bl->cone[ct][coff + 19 + 18 * (n - 1) + 13] = 3;
294 bl->cone[ct][coff + 19 + 18 * (n - 1) + 14] = n;
295 bl->cone[ct][coff + 19 + 18 * (n - 1) + 15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
296 bl->cone[ct][coff + 19 + 18 * (n - 1) + 16] = 1;
297 bl->cone[ct][coff + 19 + 18 * (n - 1) + 17] = 4;
298 bl->cone[ct][coff + 19 + 18 * (n - 1) + 18] = n;
299 for (i = 0; i < No; ++i) bl->ornt[ct][i] = 0;
300 /* DM_POLYTOPE_QUAD_PRISM_TENSOR produces n quads and n+1 tensor quad prisms */
301 ct = DM_POLYTOPE_QUAD_PRISM_TENSOR;
302 bl->Nt[ct] = 2;
303 Nc = 16 * n + 23 * 2 + 22 * (n - 1);
304 No = 4 * n + 6 * (n + 1);
305 PetscCall(PetscMalloc4(bl->Nt[ct], &bl->target[ct], bl->Nt[ct], &bl->size[ct], Nc, &bl->cone[ct], No, &bl->ornt[ct]));
306 bl->target[ct][0] = DM_POLYTOPE_QUADRILATERAL;
307 bl->target[ct][1] = DM_POLYTOPE_QUAD_PRISM_TENSOR;
308 bl->size[ct][0] = n;
309 bl->size[ct][1] = n + 1;
310 /* cones for quads */
311 for (i = 0; i < n; ++i) {
312 bl->cone[ct][16 * i + 0] = DM_POLYTOPE_SEGMENT;
313 bl->cone[ct][16 * i + 1] = 1;
314 bl->cone[ct][16 * i + 2] = 2;
315 bl->cone[ct][16 * i + 3] = i;
316 bl->cone[ct][16 * i + 4] = DM_POLYTOPE_SEGMENT;
317 bl->cone[ct][16 * i + 5] = 1;
318 bl->cone[ct][16 * i + 6] = 3;
319 bl->cone[ct][16 * i + 7] = i;
320 bl->cone[ct][16 * i + 8] = DM_POLYTOPE_SEGMENT;
321 bl->cone[ct][16 * i + 9] = 1;
322 bl->cone[ct][16 * i + 10] = 4;
323 bl->cone[ct][16 * i + 11] = i;
324 bl->cone[ct][16 * i + 12] = DM_POLYTOPE_SEGMENT;
325 bl->cone[ct][16 * i + 13] = 1;
326 bl->cone[ct][16 * i + 14] = 5;
327 bl->cone[ct][16 * i + 15] = i;
328 }
329 /* cones for quad prisms */
330 coff = 16 * n;
331 bl->cone[ct][coff + 0] = DM_POLYTOPE_QUADRILATERAL;
332 bl->cone[ct][coff + 1] = 1;
333 bl->cone[ct][coff + 2] = 0;
334 bl->cone[ct][coff + 3] = 0;
335 bl->cone[ct][coff + 4] = DM_POLYTOPE_QUADRILATERAL;
336 bl->cone[ct][coff + 5] = 0;
337 bl->cone[ct][coff + 6] = 0;
338 bl->cone[ct][coff + 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
339 bl->cone[ct][coff + 8] = 1;
340 bl->cone[ct][coff + 9] = 2;
341 bl->cone[ct][coff + 10] = 0;
342 bl->cone[ct][coff + 11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
343 bl->cone[ct][coff + 12] = 1;
344 bl->cone[ct][coff + 13] = 3;
345 bl->cone[ct][coff + 14] = 0;
346 bl->cone[ct][coff + 15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
347 bl->cone[ct][coff + 16] = 1;
348 bl->cone[ct][coff + 17] = 4;
349 bl->cone[ct][coff + 18] = 0;
350 bl->cone[ct][coff + 19] = DM_POLYTOPE_SEG_PRISM_TENSOR;
351 bl->cone[ct][coff + 20] = 1;
352 bl->cone[ct][coff + 21] = 5;
353 bl->cone[ct][coff + 22] = 0;
354 for (i = 0; i < n - 1; ++i) {
355 bl->cone[ct][coff + 23 + 22 * i + 0] = DM_POLYTOPE_QUADRILATERAL;
356 bl->cone[ct][coff + 23 + 22 * i + 1] = 0;
357 bl->cone[ct][coff + 23 + 22 * i + 2] = i;
358 bl->cone[ct][coff + 23 + 22 * i + 3] = DM_POLYTOPE_QUADRILATERAL;
359 bl->cone[ct][coff + 23 + 22 * i + 4] = 0;
360 bl->cone[ct][coff + 23 + 22 * i + 5] = i + 1;
361 bl->cone[ct][coff + 23 + 22 * i + 6] = DM_POLYTOPE_SEG_PRISM_TENSOR;
362 bl->cone[ct][coff + 23 + 22 * i + 7] = 1;
363 bl->cone[ct][coff + 23 + 22 * i + 8] = 2;
364 bl->cone[ct][coff + 23 + 22 * i + 9] = i + 1;
365 bl->cone[ct][coff + 23 + 22 * i + 10] = DM_POLYTOPE_SEG_PRISM_TENSOR;
366 bl->cone[ct][coff + 23 + 22 * i + 11] = 1;
367 bl->cone[ct][coff + 23 + 22 * i + 12] = 3;
368 bl->cone[ct][coff + 23 + 22 * i + 13] = i + 1;
369 bl->cone[ct][coff + 23 + 22 * i + 14] = DM_POLYTOPE_SEG_PRISM_TENSOR;
370 bl->cone[ct][coff + 23 + 22 * i + 15] = 1;
371 bl->cone[ct][coff + 23 + 22 * i + 16] = 4;
372 bl->cone[ct][coff + 23 + 22 * i + 17] = i + 1;
373 bl->cone[ct][coff + 23 + 22 * i + 18] = DM_POLYTOPE_SEG_PRISM_TENSOR;
374 bl->cone[ct][coff + 23 + 22 * i + 19] = 1;
375 bl->cone[ct][coff + 23 + 22 * i + 20] = 5;
376 bl->cone[ct][coff + 23 + 22 * i + 21] = i + 1;
377 }
378 bl->cone[ct][coff + 23 + 22 * (n - 1) + 0] = DM_POLYTOPE_QUADRILATERAL;
379 bl->cone[ct][coff + 23 + 22 * (n - 1) + 1] = 0;
380 bl->cone[ct][coff + 23 + 22 * (n - 1) + 2] = n - 1;
381 bl->cone[ct][coff + 23 + 22 * (n - 1) + 3] = DM_POLYTOPE_QUADRILATERAL;
382 bl->cone[ct][coff + 23 + 22 * (n - 1) + 4] = 1;
383 bl->cone[ct][coff + 23 + 22 * (n - 1) + 5] = 1;
384 bl->cone[ct][coff + 23 + 22 * (n - 1) + 6] = 0;
385 bl->cone[ct][coff + 23 + 22 * (n - 1) + 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
386 bl->cone[ct][coff + 23 + 22 * (n - 1) + 8] = 1;
387 bl->cone[ct][coff + 23 + 22 * (n - 1) + 9] = 2;
388 bl->cone[ct][coff + 23 + 22 * (n - 1) + 10] = n;
389 bl->cone[ct][coff + 23 + 22 * (n - 1) + 11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
390 bl->cone[ct][coff + 23 + 22 * (n - 1) + 12] = 1;
391 bl->cone[ct][coff + 23 + 22 * (n - 1) + 13] = 3;
392 bl->cone[ct][coff + 23 + 22 * (n - 1) + 14] = n;
393 bl->cone[ct][coff + 23 + 22 * (n - 1) + 15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
394 bl->cone[ct][coff + 23 + 22 * (n - 1) + 16] = 1;
395 bl->cone[ct][coff + 23 + 22 * (n - 1) + 17] = 4;
396 bl->cone[ct][coff + 23 + 22 * (n - 1) + 18] = n;
397 bl->cone[ct][coff + 23 + 22 * (n - 1) + 19] = DM_POLYTOPE_SEG_PRISM_TENSOR;
398 bl->cone[ct][coff + 23 + 22 * (n - 1) + 20] = 1;
399 bl->cone[ct][coff + 23 + 22 * (n - 1) + 21] = 5;
400 bl->cone[ct][coff + 23 + 22 * (n - 1) + 22] = n;
401 for (i = 0; i < No; ++i) bl->ornt[ct][i] = 0;
402 PetscFunctionReturn(PETSC_SUCCESS);
403 }
404
DMPlexTransformGetSubcellOrientation_BL(DMPlexTransform tr,DMPolytopeType sct,PetscInt sp,PetscInt so,DMPolytopeType tct,PetscInt r,PetscInt o,PetscInt * rnew,PetscInt * onew)405 static PetscErrorCode DMPlexTransformGetSubcellOrientation_BL(DMPlexTransform tr, DMPolytopeType sct, PetscInt sp, PetscInt so, DMPolytopeType tct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
406 {
407 DMPlexRefine_BL *bl = (DMPlexRefine_BL *)tr->data;
408 const PetscInt n = bl->n;
409 PetscInt tquad_tquad_o[] = {0, 1, -2, -1, 1, 0, -1, -2, -2, -1, 0, 1, -1, -2, 1, 0};
410
411 PetscFunctionBeginHot;
412 *rnew = r;
413 *onew = o;
414 if (tr->trType) {
415 PetscInt rt;
416
417 PetscCall(DMLabelGetValue(tr->trType, sp, &rt));
418 if ((rt != DM_POLYTOPE_POINT_PRISM_TENSOR + 1) && (rt != DM_POLYTOPE_SEG_PRISM_TENSOR + 2) && (rt != DM_POLYTOPE_TRI_PRISM_TENSOR + 3) && (rt != DM_POLYTOPE_QUAD_PRISM_TENSOR + 4)) {
419 PetscCall(DMPlexTransformGetSubcellOrientationIdentity(tr, sct, sp, so, tct, r, o, rnew, onew));
420 PetscFunctionReturn(PETSC_SUCCESS);
421 }
422 }
423 switch (sct) {
424 case DM_POLYTOPE_POINT_PRISM_TENSOR:
425 switch (tct) {
426 case DM_POLYTOPE_POINT:
427 *rnew = !so ? r : n - 1 - r;
428 break;
429 case DM_POLYTOPE_POINT_PRISM_TENSOR:
430 if (!so) {
431 *rnew = r;
432 *onew = o;
433 } else {
434 *rnew = n - r;
435 *onew = -(o + 1);
436 }
437 default:
438 break;
439 }
440 break;
441 case DM_POLYTOPE_SEG_PRISM_TENSOR:
442 switch (tct) {
443 case DM_POLYTOPE_SEGMENT:
444 *onew = (so == 0) || (so == 1) ? o : -(o + 1);
445 *rnew = (so == 0) || (so == -1) ? r : n - 1 - r;
446 break;
447 case DM_POLYTOPE_SEG_PRISM_TENSOR:
448 *onew = tquad_tquad_o[(so + 2) * 4 + o + 2];
449 *rnew = (so == 0) || (so == -1) ? r : n - r;
450 break;
451 default:
452 break;
453 }
454 break;
455 default:
456 PetscCall(DMPlexTransformGetSubcellOrientationIdentity(tr, sct, sp, so, tct, r, o, rnew, onew));
457 }
458 PetscFunctionReturn(PETSC_SUCCESS);
459 }
460
DMPlexTransformCellTransform_BL(DMPlexTransform tr,DMPolytopeType source,PetscInt p,PetscInt * rt,PetscInt * Nt,DMPolytopeType * target[],PetscInt * size[],PetscInt * cone[],PetscInt * ornt[])461 static PetscErrorCode DMPlexTransformCellTransform_BL(DMPlexTransform tr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
462 {
463 DMPlexRefine_BL *bl = (DMPlexRefine_BL *)tr->data;
464
465 PetscFunctionBeginHot;
466 if (rt) *rt = -1;
467 if (tr->trType && p >= 0) {
468 PetscInt val;
469
470 PetscCall(DMLabelGetValue(tr->trType, p, &val));
471 if (rt) *rt = val;
472 if ((val != DM_POLYTOPE_POINT_PRISM_TENSOR + 1) && (val != DM_POLYTOPE_SEG_PRISM_TENSOR + 2) && (val != DM_POLYTOPE_TRI_PRISM_TENSOR + 3) && (val != DM_POLYTOPE_QUAD_PRISM_TENSOR + 4)) {
473 PetscCall(DMPlexTransformCellTransformIdentity(tr, source, p, NULL, Nt, target, size, cone, ornt));
474 PetscFunctionReturn(PETSC_SUCCESS);
475 }
476 }
477 if (bl->Nt[source] < 0) {
478 PetscCall(DMPlexTransformCellTransformIdentity(tr, source, p, NULL, Nt, target, size, cone, ornt));
479 } else {
480 *Nt = bl->Nt[source];
481 *target = bl->target[source];
482 *size = bl->size[source];
483 *cone = bl->cone[source];
484 *ornt = bl->ornt[source];
485 }
486 PetscFunctionReturn(PETSC_SUCCESS);
487 }
488
DMPlexTransformMapCoordinates_BL(DMPlexTransform tr,DMPolytopeType pct,DMPolytopeType ct,PetscInt p,PetscInt r,PetscInt Nv,PetscInt dE,const PetscScalar in[],PetscScalar out[])489 static PetscErrorCode DMPlexTransformMapCoordinates_BL(DMPlexTransform tr, DMPolytopeType pct, DMPolytopeType ct, PetscInt p, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[])
490 {
491 DMPlexRefine_BL *bl = (DMPlexRefine_BL *)tr->data;
492 PetscInt d;
493
494 PetscFunctionBeginHot;
495 switch (pct) {
496 case DM_POLYTOPE_POINT_PRISM_TENSOR:
497 PetscCheck(ct == DM_POLYTOPE_POINT, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not for target point type %s", DMPolytopeTypes[ct]);
498 PetscCheck(Nv == 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Number of parent vertices %" PetscInt_FMT " != 2", Nv);
499 PetscCheck(r < bl->n && r >= 0, PETSC_COMM_SELF, PETSC_ERR_SUP, "Invalid replica %" PetscInt_FMT ", must be in [0, %" PetscInt_FMT ")", r, bl->n);
500 for (d = 0; d < dE; ++d) out[d] = in[d] + bl->h[r] * (in[d + dE] - in[d]);
501 break;
502 default:
503 PetscCall(DMPlexTransformMapCoordinatesBarycenter_Internal(tr, pct, ct, p, r, Nv, dE, in, out));
504 }
505 PetscFunctionReturn(PETSC_SUCCESS);
506 }
507
DMPlexTransformSetFromOptions_BL(DMPlexTransform tr,PetscOptionItems PetscOptionsObject)508 static PetscErrorCode DMPlexTransformSetFromOptions_BL(DMPlexTransform tr, PetscOptionItems PetscOptionsObject)
509 {
510 DMPlexRefine_BL *bl = (DMPlexRefine_BL *)tr->data;
511 PetscInt cells[256], n = 256, i;
512 PetscBool flg;
513
514 PetscFunctionBegin;
515 PetscOptionsHeadBegin(PetscOptionsObject, "DMPlexTransform Boundary Layer Options");
516 PetscCall(PetscOptionsBoundedInt("-dm_plex_transform_bl_splits", "Number of divisions of a cell", "", bl->n, &bl->n, NULL, 1));
517 PetscCall(PetscOptionsReal("-dm_plex_transform_bl_height_factor", "Factor increase for height at each division", "", bl->r, &bl->r, NULL));
518 PetscCall(PetscOptionsIntArray("-dm_plex_transform_bl_ref_cell", "Mark cells for refinement", "", cells, &n, &flg));
519 if (flg) {
520 DMLabel active;
521
522 PetscCall(DMLabelCreate(PETSC_COMM_SELF, "Adaptation Label", &active));
523 for (i = 0; i < n; ++i) PetscCall(DMLabelSetValue(active, cells[i], DM_ADAPT_REFINE));
524 PetscCall(DMPlexTransformSetActive(tr, active));
525 PetscCall(DMLabelDestroy(&active));
526 }
527 PetscOptionsHeadEnd();
528 PetscFunctionReturn(PETSC_SUCCESS);
529 }
530
DMPlexTransformView_BL(DMPlexTransform tr,PetscViewer viewer)531 static PetscErrorCode DMPlexTransformView_BL(DMPlexTransform tr, PetscViewer viewer)
532 {
533 PetscBool isascii;
534
535 PetscFunctionBegin;
536 PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
537 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
538 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
539 if (isascii) {
540 PetscViewerFormat format;
541 const char *name;
542
543 PetscCall(PetscObjectGetName((PetscObject)tr, &name));
544 PetscCall(PetscViewerASCIIPrintf(viewer, "Boundary Layer refinement %s\n", name ? name : ""));
545 PetscCall(PetscViewerGetFormat(viewer, &format));
546 if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscCall(DMLabelView(tr->trType, viewer));
547 } else {
548 SETERRQ(PetscObjectComm((PetscObject)tr), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlexTransform writing", ((PetscObject)viewer)->type_name);
549 }
550 PetscFunctionReturn(PETSC_SUCCESS);
551 }
552
DMPlexTransformDestroy_BL(DMPlexTransform tr)553 static PetscErrorCode DMPlexTransformDestroy_BL(DMPlexTransform tr)
554 {
555 DMPlexRefine_BL *bl = (DMPlexRefine_BL *)tr->data;
556 PetscInt ict;
557
558 PetscFunctionBegin;
559 for (ict = 0; ict < DM_NUM_POLYTOPES; ++ict) PetscCall(PetscFree4(bl->target[ict], bl->size[ict], bl->cone[ict], bl->ornt[ict]));
560 PetscCall(PetscFree5(bl->Nt, bl->target, bl->size, bl->cone, bl->ornt));
561 PetscCall(PetscFree(bl->h));
562 PetscCall(PetscFree(tr->data));
563 PetscFunctionReturn(PETSC_SUCCESS);
564 }
565
DMPlexTransformInitialize_BL(DMPlexTransform tr)566 static PetscErrorCode DMPlexTransformInitialize_BL(DMPlexTransform tr)
567 {
568 PetscFunctionBegin;
569 tr->ops->view = DMPlexTransformView_BL;
570 tr->ops->setfromoptions = DMPlexTransformSetFromOptions_BL;
571 tr->ops->setup = DMPlexTransformSetUp_BL;
572 tr->ops->destroy = DMPlexTransformDestroy_BL;
573 tr->ops->setdimensions = DMPlexTransformSetDimensions_Internal;
574 tr->ops->celltransform = DMPlexTransformCellTransform_BL;
575 tr->ops->getsubcellorientation = DMPlexTransformGetSubcellOrientation_BL;
576 tr->ops->mapcoordinates = DMPlexTransformMapCoordinates_BL;
577 PetscFunctionReturn(PETSC_SUCCESS);
578 }
579
DMPlexTransformCreate_BL(DMPlexTransform tr)580 PETSC_EXTERN PetscErrorCode DMPlexTransformCreate_BL(DMPlexTransform tr)
581 {
582 DMPlexRefine_BL *bl;
583
584 PetscFunctionBegin;
585 PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
586 PetscCall(PetscNew(&bl));
587 tr->data = bl;
588
589 bl->n = 1; /* 1 split -> 2 new cells */
590 bl->r = 1; /* linear coordinate progression */
591
592 PetscCall(DMPlexTransformInitialize_BL(tr));
593 PetscFunctionReturn(PETSC_SUCCESS);
594 }
595