1 /**@file
2 *
3 * An obscure basis-function set, which lives on the master-elements
4 * of a given trace-mesh, e.g. to augment a given finite element space
5 * with trace-bubbles and the like.
6 *
7 * Mmmh. To complicated. Abandoned in favour of a bulk-trace-bubble.
8 *
9 * author: Claus-Justus Heine
10 * Abteilung fuer Angewandte Mathematik
11 * Albert-Ludwigs-Universitaet Freiburg
12 * Hermann-Herder-Str. 10
13 * 79104 Freiburg i.Br.
14 * Germany
15 * claus@mathematik.uni-freiburg.de
16 *
17 * Copyright (C) by Claus-Justus Heine (2008).
18 *
19 */
20
21 #if HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include <alberta.h>
26
27 #include "albas.h"
28
29 typedef struct trace_bulk_data
30 {
31 const EL *cur_el;
32 const EL_INFO *cur_el_info;
33 int cur_wall;
34 const EL *cur_tr_el;
35 INIT_EL_TAG_CTX tag_ctx; /**< Tag context for caching purposes. */
36 MESH *trace_mesh; /**< Out dedicated trace mesh. */
37 const BAS_FCTS *bulk_bfcts; /**< The local basis function set in the bulk.*/
38 INIT_EL_TAG bulk_tag;
39 const int *trace_dof_map;
40 EL_BNDRY_VEC *bndry_loc;
41 EL_REAL_VEC_D *ipol_dow_loc;
42 EL_REAL_VEC *ipol_loc;
43 EL_REAL_D_VEC *ipol_d_loc;
44 strucbult bfcts {
45 BAS_FCT *phi;
46 GRD_BAS_FCT *grd_phi;
47 D2_BAS_FCT *D2_phi;
48 BAS_FCT_D *phi_d;
49 GRD_BAS_FCT_D *grd_phi_d;
50 D2_BAS_FCT_D *D2_phi_d;
51 } bfcts[N_WALLS_MAX];
52 bool dir_pw_const;
53 } TB_DATA;
54
tb_phi(const REAL_B lambda,const BAS_FCTS * self,int nr)55 static REAL tb_phi(const REAL_B lambda, const BAS_FCTS *self, int nr)
56 {
57 TB_DATA *data = (TB_DATA *)self->ext_data;
58
59 return PHI(data->bulk_bfcts, nr, lambda);
60 }
61
tb_grd_phi(const REAL_B lambda,const BAS_FCTS * self,int nr)62 static const REAL *tb_grd_phi(const REAL_B lambda, const BAS_FCTS *self, int nr)
63 {
64 TB_DATA *data = (TB_DATA *)self->ext_data;
65
66 return GRD_PHI(data->bulk_bfcts, nr, lambda);
67 }
68
69 static
tb_D2_phi(const REAL_B lambda,const BAS_FCTS * self,int nr)70 const REAL_B *tb_D2_phi(const REAL_B lambda, const BAS_FCTS *self, int nr)
71 {
72 TB_DATA *data = (TB_DATA *)self->ext_data;
73
74 return D2_PHI(data->bulk_bfcts, nr, lambda);
75 }
76
tb_phi_d(const REAL_B lambda,const BAS_FCTS * self,int nr)77 static const REAL *tb_phi_d(const REAL_B lambda, const BAS_FCTS *self, int nr)
78 {
79 TB_DATA *data = (TB_DATA *)self->ext_data;
80
81 return PHI_D(data->bulk_bfcts, nr, lambda);
82 }
83
84 static
tb_grd_phi_d(const REAL_B lambda,const BAS_FCTS * self,int nr)85 const REAL_B *tb_grd_phi_d(const REAL_B lambda, const BAS_FCTS *self, int nr)
86 {
87 TB_DATA *data = (TB_DATA *)self->ext_data;
88
89 return GRD_PHI_D(data->bulk_bfcts, nr, lambda);
90 }
91
92 static
tb_D2_phi_d(const REAL_B lambda,const BAS_FCTS * self,int nr)93 const REAL_BB *tb_D2_phi_d(const REAL_B lambda, const BAS_FCTS *self, int nr)
94 {
95 TB_DATA *data = (TB_DATA *)self->ext_data;
96
97 return D2_PHI_D(data->bulk_bfcts, nr, lambda);
98 }
99
100 #ifdef DEFUN_PHI
101 # undef DEFUN_PHI
102 #endif
103 #define DEFUN_PHI(nr) \
104 static REAL tb_phi_##nr(const REAL_B lambda, const BAS_FCTS *self) \
105 { \
106 return PHI(self, nr, lambda); \
107 } \
108 static \
109 const REAL *tb_grd_phi_##nr(const REAL_B lambda, const BAS_FCTS *self) \
110 { \
111 return GRD_PHI(self, nr, lambda); \
112 } \
113 static \
114 const REAL_B *tb_D2_phi_##nr(const REAL_B lambda, const BAS_FCTS *self) \
115 { \
116 return D2_PHI(self, nr, lambda); \
117 } \
118 static const REAL *tb_phi_d_##nr(const REAL_B lambda, const BAS_FCTS *self) \
119 { \
120 return PHI_D(self, nr, lambda); \
121 } \
122 static \
123 const REAL_B *tb_grd_phi_d_##nr(const REAL_B lambda, const BAS_FCTS *self) \
124 { \
125 return GRD_PHI_D(self, nr, lambda); \
126 } \
127 static \
128 const REAL_BB *tb_D2_phi_d_##nr(const REAL_B lambda, const BAS_FCTS *self) \
129 { \
130 return D2_PHI_D(self, nr, lambda); \
131 } \
132 struct _AI_semicolon_dummy
133
134 DEFUN_PHI(0);
135 DEFUN_PHI(1);
136 DEFUN_PHI(2);
137 DEFUN_PHI(3);
138 DEFUN_PHI(4);
139 DEFUN_PHI(5);
140 DEFUN_PHI(6);
141 DEFUN_PHI(7);
142 DEFUN_PHI(8);
143 DEFUN_PHI(9);
144
145 DEFUN_PHI(10);
146 DEFUN_PHI(11);
147 DEFUN_PHI(12);
148 DEFUN_PHI(13);
149 DEFUN_PHI(14);
150 DEFUN_PHI(15);
151 DEFUN_PHI(16);
152 DEFUN_PHI(17);
153 DEFUN_PHI(18);
154 DEFUN_PHI(19);
155
156 DEFUN_PHI(20);
157 DEFUN_PHI(21);
158 DEFUN_PHI(22);
159 DEFUN_PHI(23);
160 DEFUN_PHI(24);
161 DEFUN_PHI(25);
162 DEFUN_PHI(26);
163 DEFUN_PHI(27);
164 DEFUN_PHI(28);
165 DEFUN_PHI(29);
166
167 DEFUN_PHI(30);
168 DEFUN_PHI(31);
169 DEFUN_PHI(32);
170 DEFUN_PHI(33);
171 DEFUN_PHI(34);
172 DEFUN_PHI(35);
173 DEFUN_PHI(36);
174 DEFUN_PHI(37);
175 DEFUN_PHI(38);
176 DEFUN_PHI(39);
177
178 DEFUN_PHI(40);
179 DEFUN_PHI(41);
180 DEFUN_PHI(42);
181 DEFUN_PHI(43);
182 DEFUN_PHI(44);
183 DEFUN_PHI(45);
184 DEFUN_PHI(46);
185 DEFUN_PHI(47);
186 DEFUN_PHI(48);
187 DEFUN_PHI(49);
188
189 DEFUN_PHI(50);
190 DEFUN_PHI(51);
191 DEFUN_PHI(52);
192 DEFUN_PHI(53);
193 DEFUN_PHI(54);
194 DEFUN_PHI(55);
195 DEFUN_PHI(56);
196 DEFUN_PHI(57);
197 DEFUN_PHI(58);
198 DEFUN_PHI(59);
199
200 static BAS_FCT phi_table[] = {
201 tb_phi_0, tb_phi_1, tb_phi_2, tb_phi_3, tb_phi_4,
202 tb_phi_5, tb_phi_6, tb_phi_7, tb_phi_8, tb_phi_9,
203
204 tb_phi_10, tb_phi_11, tb_phi_12, tb_phi_13, tb_phi_14,
205 tb_phi_15, tb_phi_16, tb_phi_17, tb_phi_18, tb_phi_19,
206
207 tb_phi_20, tb_phi_21, tb_phi_22, tb_phi_23, tb_phi_24,
208 tb_phi_25, tb_phi_26, tb_phi_27, tb_phi_28, tb_phi_29,
209
210 tb_phi_30, tb_phi_31, tb_phi_32, tb_phi_33, tb_phi_34,
211 tb_phi_35, tb_phi_36, tb_phi_37, tb_phi_38, tb_phi_39,
212
213 tb_phi_40, tb_phi_41, tb_phi_42, tb_phi_43, tb_phi_44,
214 tb_phi_45, tb_phi_46, tb_phi_47, tb_phi_48, tb_phi_49,
215
216 tb_phi_50, tb_phi_51, tb_phi_52, tb_phi_53, tb_phi_54,
217 tb_phi_55, tb_phi_56, tb_phi_57, tb_phi_58, tb_phi_59,
218 };
219
220 static GRD_BAS_FCT grd_phi_table[] = {
221 tb_grd_phi_0, tb_grd_phi_1, tb_grd_phi_2, tb_grd_phi_3, tb_grd_phi_4,
222 tb_grd_phi_5, tb_grd_phi_6, tb_grd_phi_7, tb_grd_phi_8, tb_grd_phi_9,
223
224 tb_grd_phi_10, tb_grd_phi_11, tb_grd_phi_12, tb_grd_phi_13, tb_grd_phi_14,
225 tb_grd_phi_15, tb_grd_phi_16, tb_grd_phi_17, tb_grd_phi_18, tb_grd_phi_19,
226
227 tb_grd_phi_20, tb_grd_phi_21, tb_grd_phi_22, tb_grd_phi_23, tb_grd_phi_24,
228 tb_grd_phi_25, tb_grd_phi_26, tb_grd_phi_27, tb_grd_phi_28, tb_grd_phi_29,
229
230 tb_grd_phi_30, tb_grd_phi_31, tb_grd_phi_32, tb_grd_phi_33, tb_grd_phi_34,
231 tb_grd_phi_35, tb_grd_phi_36, tb_grd_phi_37, tb_grd_phi_38, tb_grd_phi_39,
232
233 tb_grd_phi_40, tb_grd_phi_41, tb_grd_phi_42, tb_grd_phi_43, tb_grd_phi_44,
234 tb_grd_phi_45, tb_grd_phi_46, tb_grd_phi_47, tb_grd_phi_48, tb_grd_phi_49,
235
236 tb_grd_phi_50, tb_grd_phi_51, tb_grd_phi_52, tb_grd_phi_53, tb_grd_phi_54,
237 tb_grd_phi_55, tb_grd_phi_56, tb_grd_phi_57, tb_grd_phi_58, tb_grd_phi_59,
238 };
239
240 static D2_BAS_FCT D2_phi_table[] = {
241 tb_D2_phi_0, tb_D2_phi_1, tb_D2_phi_2, tb_D2_phi_3, tb_D2_phi_4,
242 tb_D2_phi_5, tb_D2_phi_6, tb_D2_phi_7, tb_D2_phi_8, tb_D2_phi_9,
243
244 tb_D2_phi_10, tb_D2_phi_11, tb_D2_phi_12, tb_D2_phi_13, tb_D2_phi_14,
245 tb_D2_phi_15, tb_D2_phi_16, tb_D2_phi_17, tb_D2_phi_18, tb_D2_phi_19,
246
247 tb_D2_phi_20, tb_D2_phi_21, tb_D2_phi_22, tb_D2_phi_23, tb_D2_phi_24,
248 tb_D2_phi_25, tb_D2_phi_26, tb_D2_phi_27, tb_D2_phi_28, tb_D2_phi_29,
249
250 tb_D2_phi_30, tb_D2_phi_31, tb_D2_phi_32, tb_D2_phi_33, tb_D2_phi_34,
251 tb_D2_phi_35, tb_D2_phi_36, tb_D2_phi_37, tb_D2_phi_38, tb_D2_phi_39,
252
253 tb_D2_phi_40, tb_D2_phi_41, tb_D2_phi_42, tb_D2_phi_43, tb_D2_phi_44,
254 tb_D2_phi_45, tb_D2_phi_46, tb_D2_phi_47, tb_D2_phi_48, tb_D2_phi_49,
255
256 tb_D2_phi_50, tb_D2_phi_51, tb_D2_phi_52, tb_D2_phi_53, tb_D2_phi_54,
257 tb_D2_phi_55, tb_D2_phi_56, tb_D2_phi_57, tb_D2_phi_58, tb_D2_phi_59,
258 };
259
260 static BAS_FCT_D phi_d_table[] = {
261 tb_phi_d_0, tb_phi_d_1, tb_phi_d_2, tb_phi_d_3, tb_phi_d_4,
262 tb_phi_d_5, tb_phi_d_6, tb_phi_d_7, tb_phi_d_8, tb_phi_d_9,
263
264 tb_phi_d_10, tb_phi_d_11, tb_phi_d_12, tb_phi_d_13, tb_phi_d_14,
265 tb_phi_d_15, tb_phi_d_16, tb_phi_d_17, tb_phi_d_18, tb_phi_d_19,
266
267 tb_phi_d_20, tb_phi_d_21, tb_phi_d_22, tb_phi_d_23, tb_phi_d_24,
268 tb_phi_d_25, tb_phi_d_26, tb_phi_d_27, tb_phi_d_28, tb_phi_d_29,
269
270 tb_phi_d_30, tb_phi_d_31, tb_phi_d_32, tb_phi_d_33, tb_phi_d_34,
271 tb_phi_d_35, tb_phi_d_36, tb_phi_d_37, tb_phi_d_38, tb_phi_d_39,
272
273 tb_phi_d_40, tb_phi_d_41, tb_phi_d_42, tb_phi_d_43, tb_phi_d_44,
274 tb_phi_d_45, tb_phi_d_46, tb_phi_d_47, tb_phi_d_48, tb_phi_d_49,
275
276 tb_phi_d_50, tb_phi_d_51, tb_phi_d_52, tb_phi_d_53, tb_phi_d_54,
277 tb_phi_d_55, tb_phi_d_56, tb_phi_d_57, tb_phi_d_58, tb_phi_d_59,
278 };
279
280 static GRD_BAS_FCT_D grd_phi_d_table[] = {
281 tb_grd_phi_d_0, tb_grd_phi_d_1, tb_grd_phi_d_2, tb_grd_phi_d_3,
282 tb_grd_phi_d_4,
283 tb_grd_phi_d_5, tb_grd_phi_d_6, tb_grd_phi_d_7, tb_grd_phi_d_8,
284 tb_grd_phi_d_9,
285
286 tb_grd_phi_d_10, tb_grd_phi_d_11, tb_grd_phi_d_12, tb_grd_phi_d_13,
287 tb_grd_phi_d_14,
288 tb_grd_phi_d_15, tb_grd_phi_d_16, tb_grd_phi_d_17, tb_grd_phi_d_18,
289 tb_grd_phi_d_19,
290
291 tb_grd_phi_d_20, tb_grd_phi_d_21, tb_grd_phi_d_22, tb_grd_phi_d_23,
292 tb_grd_phi_d_24,
293 tb_grd_phi_d_25, tb_grd_phi_d_26, tb_grd_phi_d_27, tb_grd_phi_d_28,
294 tb_grd_phi_d_29,
295
296 tb_grd_phi_d_30, tb_grd_phi_d_31, tb_grd_phi_d_32, tb_grd_phi_d_33,
297 tb_grd_phi_d_34,
298 tb_grd_phi_d_35, tb_grd_phi_d_36, tb_grd_phi_d_37, tb_grd_phi_d_38,
299 tb_grd_phi_d_39,
300
301 tb_grd_phi_d_40, tb_grd_phi_d_41, tb_grd_phi_d_42, tb_grd_phi_d_43,
302 tb_grd_phi_d_44,
303 tb_grd_phi_d_45, tb_grd_phi_d_46, tb_grd_phi_d_47, tb_grd_phi_d_48,
304 tb_grd_phi_d_49,
305
306 tb_grd_phi_d_50, tb_grd_phi_d_51, tb_grd_phi_d_52, tb_grd_phi_d_53,
307 tb_grd_phi_d_54,
308 tb_grd_phi_d_55, tb_grd_phi_d_56, tb_grd_phi_d_57, tb_grd_phi_d_58,
309 tb_grd_phi_d_59,
310 };
311
312 static D2_BAS_FCT_D D2_phi_d_table[] = {
313 tb_D2_phi_d_0, tb_D2_phi_d_1, tb_D2_phi_d_2, tb_D2_phi_d_3,
314 tb_D2_phi_d_4,
315 tb_D2_phi_d_5, tb_D2_phi_d_6, tb_D2_phi_d_7, tb_D2_phi_d_8,
316 tb_D2_phi_d_9,
317
318 tb_D2_phi_d_10, tb_D2_phi_d_11, tb_D2_phi_d_12, tb_D2_phi_d_13,
319 tb_D2_phi_d_14,
320 tb_D2_phi_d_15, tb_D2_phi_d_16, tb_D2_phi_d_17, tb_D2_phi_d_18,
321 tb_D2_phi_d_19,
322
323 tb_D2_phi_d_20, tb_D2_phi_d_21, tb_D2_phi_d_22, tb_D2_phi_d_23,
324 tb_D2_phi_d_24,
325 tb_D2_phi_d_25, tb_D2_phi_d_26, tb_D2_phi_d_27, tb_D2_phi_d_28,
326 tb_D2_phi_d_29,
327
328 tb_D2_phi_d_30, tb_D2_phi_d_31, tb_D2_phi_d_32, tb_D2_phi_d_33,
329 tb_D2_phi_d_34,
330 tb_D2_phi_d_35, tb_D2_phi_d_36, tb_D2_phi_d_37, tb_D2_phi_d_38,
331 tb_D2_phi_d_39,
332
333 tb_D2_phi_d_40, tb_D2_phi_d_41, tb_D2_phi_d_42, tb_D2_phi_d_43,
334 tb_D2_phi_d_44,
335 tb_D2_phi_d_45, tb_D2_phi_d_46, tb_D2_phi_d_47, tb_D2_phi_d_48,
336 tb_D2_phi_d_49,
337
338 tb_D2_phi_d_50, tb_D2_phi_d_51, tb_D2_phi_d_52, tb_D2_phi_d_53,
339 tb_D2_phi_d_54,
340 tb_D2_phi_d_55, tb_D2_phi_d_56, tb_D2_phi_d_57, tb_D2_phi_d_58,
341 tb_D2_phi_d_59,
342 };
343
344 static const int id_map[] = {
345 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
346 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
347 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
348 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
349 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
350 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
351 };
352
353 static
fill_jump_tables(struct bfcts * jump_table,const int trace_map[],int n_trace_fcts)354 void fill_jump_tables(struct bfcts *jump_table,
355 const int trace_map[],
356 int n_trace_fcts)
357 {
358 int i;
359
360 if (jump_table->phi) {
361 for (i = 0; i < n_trace_fcts; i++) {
362 jump_table->phi[i] = phi_table[trace_map[i]];
363 }
364 }
365 if (jump_table->grd_phi) {
366 for (i = 0; i < n_trace_fcts; i++) {
367 jump_table->grd_phi[i] = grd_phi_table[trace_map[i]];
368 }
369 }
370 if (jump_table->D2_phi) {
371 for (i = 0; i < n_trace_fcts; i++) {
372 jump_table->D2_phi[i] = D2_phi_table[trace_map[i]];
373 }
374 }
375 if (jump_table->phi_d) {
376 for (i = 0; i < n_trace_fcts; i++) {
377 jump_table->phi_d[i] = phi_d_table[trace_map[i]];
378 }
379 }
380 if (jump_table->grd_phi_d) {
381 for (i = 0; i < n_trace_fcts; i++) {
382 jump_table->grd_phi_d[i] = grd_phi_d_table[trace_map[i]];
383 }
384 }
385 if (jump_table->D2_phi_d) {
386 for (i = 0; i < n_trace_fcts; i++) {
387 jump_table->D2_phi_d[i] = D2_phi_d_table[trace_map[i]];
388 }
389 }
390 }
391
392 static
trace_bulk_init_element(const EL_INFO * el_info,void * thisptr)393 INIT_EL_TAG trace_bulk_init_element(const EL_INFO *el_info, void *thisptr)
394 {
395 FUNCNAME("trace_bulk_init_element");
396 BAS_FCTS *self = (BAS_FCTS *)thisptr;
397 TB_DATA *data = (TB_DATA *)self->ext_data;
398 MESH *mesh;
399 int w, dim;
400 INIT_EL_TAG bulk_tag;
401 const EL *tr_el;
402
403 if (el_info == NULL) {
404 self->n_bas_fcts = 0;
405 self->dir_pw_const = true;
406 data->cur_el = NULL;
407 data->cur_el_info = NULL;
408 INIT_OBJECT(data->bulk_bfcts);
409 INIT_EL_TAG_CTX_DFLT(&data->tag_ctx);
410 return INIT_EL_TAG_CTX_TAG(&data->tag_ctx);
411 }
412
413 if (data->cur_el == el_info->el && data->cur_el_info == el_info) {
414 return INIT_EL_TAG_CTX_TAG(&data->tag_ctx);
415 }
416 data->cur_el = el_info->el;
417 data->cur_el_info = el_info;
418
419 mesh = el_info->mesh;
420 dim = mesh->dim;
421
422 for (w = 0; w < N_WALLS(dim); w++) {
423 int o, t;
424 if ((tr_el = get_slave_el(el_info->el, w, data->trace_mesh)) == NULL) {
425 continue;
426 }
427 bulk_tag = INIT_ELEMENT(el_info, data->bulk_bfcts);
428 TEST_EXIT(bulk_tag == INIT_EL_TAG_DFLT);
429 o = el_info->orientation < 0;
430 t = el_info->el_type > 0;
431 data->trace_dof_map = data->bulk_bfcts->trace_dof_map[t][o][w];
432 if (data->cur_wall != w || bulk_tag != data->bulk_tag) {
433 data->bndry_loc->n_components = data->bulk_bfcts->n_trace_bas_fcts[w];
434 self->phi = data->bfcts[w].phi;
435 self->grd_phi = data->bfcts[w].grd_phi;
436 self->d2_phi = data->bfcts[w].d2_phi;
437 self->phi_d = data->bfcts[w].phi_d;
438 self->grd_phi_d = data->bfcts[w].grd_phi_d;
439 self->d2_phi_d = data->bfcts[w].d2_phi_d;
440 data->cur_wall = w;
441 self->dir_pw_const = data->dir_pw_const;
442 INIT_EL_TAG_CTX_UNIQ(&self->tag_ctx);
443 }
444 data->bulk_tag = bulk_tag;
445 break;
446 }
447
448 data->tr_el = tr_el;
449
450 return INIT_EL_TAG_CTX_TAG(&data->tag_ctx);
451 }
452
453 static const EL_DOF_VEC *
tb_get_dof_indices(DOF * dof,const EL * el,const DOF_ADMIN * admin,const BAS_FCTGS * self)454 tb_get_dof_indices(DOF *dof,
455 const EL *el,
456 const DOF_ADMIN *admin,
457 const BAS_FCTGS *self)
458 {
459 TB_DATA *data = (TB_DATA *)self->ext_data;
460
461 return GET_DOF_INDICES(
462 data->bulk_bfcts->trace_bas_fcts, data->tr_el, admin, dof);
463 }
464
465 static const EL_BNDRY_VEC *
tb_get_bound(BNDRY_FLAGS * bound,const EL_INFO * el_info,const BAS_FCTS * self)466 tb_get_bound(BNDRY_FLAGS *bound,
467 const EL_INFO *el_info,
468 const BAS_FCTS *self)
469 {
470 TB_DATA *data = (TB_DATA *)self->ext_data;
471 BNDRY_FLAGS bndry_loc[data->bulk_bfcts->n_bas_fcts];
472 BNDRY_FLAGS *vec = bound == NULL ? data->bndry_loc->vec : bound;
473 int i;
474
475 GET_BOUND(data->bulk_bfcts, el_info, bndry_loc);
476 for (i = 0; i < self->n_bas_fcts; i++) {
477 vec[i] = bndry_loc[data->trace_dof_map[i]];
478 }
479 return bound == NULL ? data->bndry_loc : bound;
480 }
481
tb_interpol(EL_REAL_VEC * coeff,const EL_INFO * el_info,int wall,int n,const int * indices,LOC_FCT_AT_QP f,void * f_data,const BAS_FCTS * thisptr)482 static void tb_interpol(EL_REAL_VEC *coeff,
483 const EL_INFO *el_info, int wall,
484 int n, const int *indices,
485 LOC_FCT_AT_QP f, void *f_data,
486 const BAS_FCTS *thisptr)
487 {
488 TB_DATA *data = (TB_DATA *)self->ext_data;
489 REAL tmp_coeff[self->n_bas_fcts];
490
491 if (wall
492
493 if (indices) {
494 int tmp_indices[data->bulk_bfcts->n_bas_fcts];
495 memcpy(tmp_coeff, coeff->vec, self->n_bas_fcts * sizeof(REAL));
496 coeff->n_components = data->bulk_bfcts->n_bas_fcts;
497 memset(coeff->vec, 0, sizeof(REAL) * coeff->n_components);
498 for (i = 0; i < coeff->n_components; i++) {
499 coeff->vec[data->trace_dof_map[i]] = tmp_coeff[i];
500 }
501 for (i = 0; i < n; i++) {
502 tmp_indices[i] = data->trace_dof_map[indices[i]];
503 }
504 INTERPOL(coeff,
505 el_info, data->cur_wall, n, tmp_indices,
506 f, f_data, data->bulk_bfcts);
507 for (i = 0; i < self->n_bas_fcts; i++) {
508 tmp_coeff[i] = coeff->vec[data->trace_dof_map[i]];
509 }
510 for (i = 0; i < self->n_bas_fcts; i++) {
511 coeff->vec[i] = temp_coeff[i];
512 }
513 } else {
514
515
516
517 if (indices == NULL) {
518 for (i = 0; i < self->n_bas_fcts; i++) {
519 tmp_coeff =
520
521 coeff->vec[i] = coeff
522 data->ipol_loc_dow[data->trace_dof_map[i]];
523 }
524 } else {
525 for (i = 0; i < n; i++) {
526 int dst = b_no[i];
527 int src = data->trace_dof_map[dst];
528 vec->vec[dst] = data->ipol_loc_dow[src];
529 }
530 }
531 }
532
533 static void tb_interpol_d(EL_REAL_D_VEC *coeff,
534 const EL_INFO *el_info, int wall,
535 int n, const int *indices,
536 LOC_FCT_D_AT_QP f, void *f_data,
537 const BAS_FCTS *thisptr)
538 {
539 TB_DATA *data = (TB_DATA *)self->ext_data;
540
541 INTERPOL_D(data->ipol_loc_dow,
542 el_info, data->cur_wall, -1, NULL, f, f_data, data->bulk_bfcts);
543
544 if (indices == NULL) {
545 for (i = 0; i < self->n_bas_fcts; i++) {
546 COPY_DOW(data->ipol_loc_dow[data->trace_dof_map[i]], vec->vec[i]);
547 }
548 } else {
549 for (i = 0; i < n; i++) {
550 int dst = b_no[i];
551 int src = data->trace_dof_map[dst];
552 COPY_DOW(data->ipol_loc_dow[src], vec->vec[dst]);
553 }
554 }
555 }
556
557 static void tb_interpol_dow(EL_REAL_VEC_D *vec,
558 const EL_INFO *el_info, int wall,
559 int no, const int *b_no,
560 LOC_FCT_D_AT_QP f, void *f_data,
561 const BAS_FCTS *self)
562 {
563 TB_DATA *data = (TB_DATA *)self->ext_data;
564
565 INTERPOL_DOW(data->ipol_loc_dow,
566 el_info, data->cur_wall, -1, NULL, f, f_data, data->bulk_bfcts);
567
568 if (b_no == NULL) {
569 for (i = 0; i < self->n_bas_fcts; i++) {
570 vec->vec[i] = data->ipol_loc_dow[data->trace_dof_map[i]];
571 }
572 } else {
573 for (i = 0; i < no; i++) {
574 int dst = b_no[i];
575 int src = data->trace_dof_map[dst];
576 vec->vec[dst] = data->ipol_loc_dow[src];
577 }
578 }
579 }
580
581 const BAS_FCTS *get_trace_bulk_space(const BAS_FCTS *bulk_bfcts,
582 MESH *trace_mesh)
583 {
584 FUNCNAME("get_trace_bulk_space");
585 BAS_FCTS *trace_bulk_bfcts;
586 TB_DATA *data;
587 int dim = bulk_bfcts->dim;
588 char *name;
589 int i;
590
591 TEST_EXIT(dim == trace_mesh->dim + 1,
592 "Wrong dimensions: bulk-bas-fcts: %d, trace-mesh: %d\n",
593 dim, trace_mesh->dim);
594
595 trace_bulk_bfcts = MEM_CALLOC(1, BAS_FCTS);
596 trace_bulk_bfcts->name = name =
597 malloc(sizeof("TraceBulk@@")+strlen(bulk_bfcts)+strlen(trace_mesh->name));
598 sprintf(name, "TraceBulk@%s@", trace_mesh->name, bulk_bfcts->name);
599 trace_bulk_bfcts->dim = bulk_bfcts->dim;
600 trace_bulk_bfcts->rdim = bulk_bfcts->rdim;
601 trace_bulk_bfcts->degree = bulk_bfcts->degree;
602 trace_bulk_bfcts->n_bas_fcts = 0;
603 /* Fake to many basis functions in order to make it easier to
604 * forward some call-back functions to the underlying bulk basis
605 * functions.
606 */
607 trace_bulk_bfcts->n_bas_fcts_max =
608 N_WALLS_MAX * bulk_bfcts->trace_bas_fcs->n_bas_fcts_max;
609
610 trace_bulk_bfcts->n_dof[VERTEX] = bulk_bfcts->trace_bas_fcs->n_dof[VERTEX];
611 trace_bulk_bfcts->n_dof[CENTER] = bulk_bfcts->trace_bas_fcs->n_dof[CENTER];
612 trace_bulk_bfcts->n_dof[EDGE] = bulk_bfcts->trace_bas_fcs->n_dof[EDGE];
613 trace_bulk_bfcts->n_dof[FACE] = bulk_bfcts->trace_bas_fcs->n_dof[FACE];
614
615 CHAIN_INIT(trace_bulk_bfcts);
616 trace_bulk_bfcts->unchained = trace_bulk_bfcts;
617
618 trace_bulk_bfcts->trace_bas_fcts = bulk_bfcts->trace_bas_fcts;
619 for (w = 0; w < N_WALLS(dim); w++) {
620 trace_bulk_bfcts->n_trace_bas_fcts = 0;
621 for (t = 0; t < 1; t++) {
622 for (o = 0; o < 1; o++) {
623 trace_bulk_bfcts->trace_dof_map[t][o][w] = id_map;
624 }
625 }
626 }
627 trace_bulk_bfcts->get_dof_indices = tb_get_dof_indices;
628 trace_bulk_bfcts->get_dof_indices = tb_get_bound;
629 trace_bulk_bfcts->interpol = tb_interpol;
630 trace_bulk_bfcts->interpol_d = tb_interpol_d;
631 trace_bulk_bfcts->interpol_dow = tb_interpol_dow;
632
633 trace_bulk_bfcts->dir_pw_const = bulk_bas_fcts->dir_pw_const;
634
635 /* Hook in the default get_FOOBAR_vec() routines */
636 trace_bulk_bfcts->get_int_vec = default_get_int_vec;
637 trace_bulk_bfcts->get_real_vec = default_get_real_vec;
638 trace_bulk_bfcts->get_real_d_vec = default_get_real_d_vec;
639 trace_bulk_bfcts->get_real_vec_d = default_get_real_vec_d;
640 trace_bulk_bfcts->get_uchar_vec = default_get_uchar_vec;
641 trace_bulk_bfcts->get_schar_vec = default_get_schar_vec;
642 trace_bulk_bfcts->get_ptr_vec = default_get_ptr_vec;
643
644 /* */
645 }
646
647