42 #ifndef GETFEM_ASSEMBLING_H__
43 #define GETFEM_ASSEMBLING_H__
54 template<
typename VEC>
58 {
return sqrt(asm_L2_norm_sqr(mim, mf, U, rg)); }
60 template<
typename VEC>
61 scalar_type asm_L2_norm_sqr
62 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
64 return asm_L2_norm_sqr(mim, mf, U, rg,
65 typename gmm::linalg_traits<VEC>::value_type());
68 template<
typename VEC,
typename T>
69 inline scalar_type asm_L2_norm_sqr(
const mesh_im &mim,
const mesh_fem &mf,
70 const VEC &U,
const mesh_region &rg_, T) {
71 ga_workspace workspace;
72 model_real_plain_vector UU(mf.nb_dof());
74 gmm::sub_interval Iu(0, mf.nb_dof());
75 workspace.add_fem_variable(
"u", mf, Iu, UU);
76 workspace.add_expression(
"u.u", mim, rg_);
77 workspace.assembly(0);
78 return workspace.assembled_potential();
81 inline scalar_type asm_L2_norm_sqr(
const mesh_im &mim,
const mesh_fem &mf,
82 const model_real_plain_vector &U,
83 const mesh_region &rg_, scalar_type) {
84 ga_workspace workspace;
85 gmm::sub_interval Iu(0, mf.nb_dof());
86 workspace.add_fem_variable(
"u", mf, Iu, U);
87 workspace.add_expression(
"u.u", mim, rg_);
88 workspace.assembly(0);
89 return workspace.assembled_potential();
92 template<
typename VEC,
typename T>
93 inline scalar_type asm_L2_norm_sqr(
const mesh_im &mim,
const mesh_fem &mf,
95 const mesh_region &rg, std::complex<T>) {
96 ga_workspace workspace;
97 model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
100 gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
101 workspace.add_fem_variable(
"u", mf, Iur, UUR);
102 workspace.add_fem_variable(
"v", mf, Iui, UUI);
103 workspace.add_expression(
"u.u + v.v", mim, rg);
104 workspace.assembly(0);
105 return workspace.assembled_potential();
114 template<
typename VEC1,
typename VEC2>
117 const mesh_fem &mf2,
const VEC2 &U2,
119 return sqrt(asm_L2_dist_sqr(mim, mf1, U1, mf2, U2, rg,
120 typename gmm::linalg_traits<VEC1>::value_type()));
123 template<
typename VEC1,
typename VEC2,
typename T>
124 inline scalar_type asm_L2_dist_sqr
125 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
126 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, T) {
127 ga_workspace workspace;
128 model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
129 gmm::copy(U1, UU1); gmm::copy(U2, UU2);
130 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
131 workspace.add_fem_variable(
"u1", mf1, Iu1, UU1);
132 workspace.add_fem_variable(
"u2", mf2, Iu2, UU2);
133 workspace.add_expression(
"(u2-u1).(u2-u1)", mim, rg);
134 workspace.assembly(0);
135 return workspace.assembled_potential();
138 inline scalar_type asm_L2_dist_sqr
139 (
const mesh_im &mim,
const mesh_fem &mf1,
const model_real_plain_vector &U1,
140 const mesh_fem &mf2,
const model_real_plain_vector &U2,
141 mesh_region rg, scalar_type) {
142 ga_workspace workspace;
143 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
144 workspace.add_fem_variable(
"u1", mf1, Iu1, U1);
145 workspace.add_fem_variable(
"u2", mf2, Iu2, U2);
146 workspace.add_expression(
"(u2-u1).(u2-u1)", mim, rg);
147 workspace.assembly(0);
148 return workspace.assembled_potential();
151 template<
typename VEC1,
typename VEC2,
typename T>
152 inline scalar_type asm_L2_dist_sqr
153 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
154 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, std::complex<T>) {
155 ga_workspace workspace;
156 model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
157 model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
160 gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
161 gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
162 gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
163 workspace.add_fem_variable(
"u1", mf1, Iu1r, UU1R);
164 workspace.add_fem_variable(
"u2", mf2, Iu2r, UU2R);
165 workspace.add_fem_variable(
"v1", mf1, Iu1i, UU1I);
166 workspace.add_fem_variable(
"v2", mf2, Iu2i, UU2I);
167 workspace.add_expression(
"(u2-u1).(u2-u1) + (v2-v1).(v2-v1)", mim, rg);
168 workspace.assembly(0);
169 return workspace.assembled_potential();
177 template<
typename VEC>
181 typedef typename gmm::linalg_traits<VEC>::value_type T;
182 return sqrt(asm_H1_semi_norm_sqr(mim, mf, U, rg, T()));
185 template<
typename VEC,
typename T>
186 inline scalar_type asm_H1_semi_norm_sqr
187 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
188 const mesh_region &rg_, T) {
189 ga_workspace workspace;
190 model_real_plain_vector UU(mf.nb_dof()); gmm::copy(U, UU);
191 gmm::sub_interval Iu(0, mf.nb_dof());
192 workspace.add_fem_variable(
"u", mf, Iu, UU);
193 workspace.add_expression(
"Grad_u:Grad_u", mim, rg_);
194 workspace.assembly(0);
195 return workspace.assembled_potential();
198 inline scalar_type asm_H1_semi_norm_sqr
199 (
const mesh_im &mim,
const mesh_fem &mf,
const model_real_plain_vector &U,
200 const mesh_region &rg_, scalar_type) {
201 ga_workspace workspace;
202 gmm::sub_interval Iu(0, mf.nb_dof());
203 workspace.add_fem_variable(
"u", mf, Iu, U);
204 workspace.add_expression(
"Grad_u:Grad_u", mim, rg_);
205 workspace.assembly(0);
206 return workspace.assembled_potential();
210 template<
typename VEC,
typename T>
211 inline scalar_type asm_H1_semi_norm_sqr
212 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
213 const mesh_region &rg, std::complex<T>) {
214 ga_workspace workspace;
215 model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
218 gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
219 workspace.add_fem_variable(
"u", mf, Iur, UUR);
220 workspace.add_fem_variable(
"v", mf, Iui, UUI);
221 workspace.add_expression(
"Grad_u:Grad_u + Grad_v:Grad_v", mim, rg);
222 workspace.assembly(0);
223 return workspace.assembled_potential();
232 template<
typename VEC1,
typename VEC2>
235 const mesh_fem &mf2,
const VEC2 &U2,
237 return sqrt(asm_H1_semi_dist_sqr(mim, mf1, U1, mf2, U2, rg,
238 typename gmm::linalg_traits<VEC1>::value_type()));
241 template<
typename VEC1,
typename VEC2,
typename T>
242 inline scalar_type asm_H1_semi_dist_sqr
243 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
244 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, T) {
245 ga_workspace workspace;
246 model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
247 gmm::copy(U1, UU1); gmm::copy(U2, UU2);
248 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
249 workspace.add_fem_variable(
"u1", mf1, Iu1, UU1);
250 workspace.add_fem_variable(
"u2", mf2, Iu2, UU2);
251 workspace.add_expression(
"(Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
252 workspace.assembly(0);
253 return workspace.assembled_potential();
256 inline scalar_type asm_H1_semi_dist_sqr
257 (
const mesh_im &mim,
const mesh_fem &mf1,
const model_real_plain_vector &U1,
258 const mesh_fem &mf2,
const model_real_plain_vector &U2,
259 mesh_region rg, scalar_type) {
260 ga_workspace workspace;
261 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
262 workspace.add_fem_variable(
"u1", mf1, Iu1, U1);
263 workspace.add_fem_variable(
"u2", mf2, Iu2, U2);
264 workspace.add_expression(
"(Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
265 workspace.assembly(0);
266 return workspace.assembled_potential();
269 template<
typename VEC1,
typename VEC2,
typename T>
270 inline scalar_type asm_H1_semi_dist_sqr
271 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
272 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, std::complex<T>) {
273 ga_workspace workspace;
274 model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
275 model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
278 gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
279 gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
280 gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
281 workspace.add_fem_variable(
"u1", mf1, Iu1r, UU1R);
282 workspace.add_fem_variable(
"u2", mf2, Iu2r, UU2R);
283 workspace.add_fem_variable(
"v1", mf1, Iu1i, UU1I);
284 workspace.add_fem_variable(
"v2", mf2, Iu2i, UU2I);
285 workspace.add_expression(
"(Grad_u2-Grad_u1):(Grad_u2-Grad_u1)"
286 "+ (Grad_v2-Grad_v1):(Grad_v2-Grad_v1)", mim, rg);
287 workspace.assembly(0);
288 return workspace.assembled_potential();
300 template<
typename VEC>
304 typedef typename gmm::linalg_traits<VEC>::value_type T;
305 return sqrt(asm_H1_norm_sqr(mim, mf, U, rg, T()));
308 template<
typename VEC,
typename T>
309 inline scalar_type asm_H1_norm_sqr
310 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
311 const mesh_region &rg_, T) {
312 ga_workspace workspace;
313 model_real_plain_vector UU(mf.nb_dof()); gmm::copy(U, UU);
314 gmm::sub_interval Iu(0, mf.nb_dof());
315 workspace.add_fem_variable(
"u", mf, Iu, UU);
316 workspace.add_expression(
"u.u + Grad_u:Grad_u", mim, rg_);
317 workspace.assembly(0);
318 return workspace.assembled_potential();
321 inline scalar_type asm_H1_norm_sqr
322 (
const mesh_im &mim,
const mesh_fem &mf,
const model_real_plain_vector &U,
323 const mesh_region &rg_, scalar_type) {
324 ga_workspace workspace;
325 gmm::sub_interval Iu(0, mf.nb_dof());
326 workspace.add_fem_variable(
"u", mf, Iu, U);
327 workspace.add_expression(
"u.u + Grad_u:Grad_u", mim, rg_);
328 workspace.assembly(0);
329 return workspace.assembled_potential();
333 template<
typename VEC,
typename T>
334 inline scalar_type asm_H1_norm_sqr
335 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
336 const mesh_region &rg, std::complex<T>) {
337 ga_workspace workspace;
338 model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
341 gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
342 workspace.add_fem_variable(
"u", mf, Iur, UUR);
343 workspace.add_fem_variable(
"v", mf, Iui, UUI);
344 workspace.add_expression(
"u.u+v.v + Grad_u:Grad_u+Grad_v:Grad_v", mim, rg);
345 workspace.assembly(0);
346 return workspace.assembled_potential();
353 template<
typename VEC1,
typename VEC2>
356 const mesh_fem &mf2,
const VEC2 &U2,
358 return sqrt(asm_H1_dist_sqr(mim, mf1, U1, mf2, U2, rg,
359 typename gmm::linalg_traits<VEC1>::value_type()));
362 template<
typename VEC1,
typename VEC2,
typename T>
363 inline scalar_type asm_H1_dist_sqr
364 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
365 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, T) {
366 ga_workspace workspace;
367 model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
368 gmm::copy(U1, UU1); gmm::copy(U2, UU2);
369 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
370 workspace.add_fem_variable(
"u1", mf1, Iu1, UU1);
371 workspace.add_fem_variable(
"u2", mf2, Iu2, UU2);
372 workspace.add_expression(
"(u2-u1).(u2-u1)"
373 "+ (Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
374 workspace.assembly(0);
375 return workspace.assembled_potential();
378 inline scalar_type asm_H1_dist_sqr
379 (
const mesh_im &mim,
const mesh_fem &mf1,
const model_real_plain_vector &U1,
380 const mesh_fem &mf2,
const model_real_plain_vector &U2,
381 mesh_region rg, scalar_type) {
382 ga_workspace workspace;
383 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
384 workspace.add_fem_variable(
"u1", mf1, Iu1, U1);
385 workspace.add_fem_variable(
"u2", mf2, Iu2, U2);
386 workspace.add_expression(
"(u2-u1).(u2-u1)"
387 "+ (Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
388 workspace.assembly(0);
389 return workspace.assembled_potential();
392 template<
typename VEC1,
typename VEC2,
typename T>
393 inline scalar_type asm_H1_dist_sqr
394 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
395 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, std::complex<T>) {
396 ga_workspace workspace;
397 model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
398 model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
401 gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
402 gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
403 gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
404 workspace.add_fem_variable(
"u1", mf1, Iu1r, UU1R);
405 workspace.add_fem_variable(
"u2", mf2, Iu2r, UU2R);
406 workspace.add_fem_variable(
"v1", mf1, Iu1i, UU1I);
407 workspace.add_fem_variable(
"v2", mf2, Iu2i, UU2I);
408 workspace.add_expression(
"(u2-u1).(u2-u1) + (v2-v1).(v2-v1)"
409 "+ (Grad_u2-Grad_u1):(Grad_u2-Grad_u1)"
410 "+ (Grad_v2-Grad_v1):(Grad_v2-Grad_v1)", mim, rg);
411 workspace.assembly(0);
412 return workspace.assembled_potential();
420 template<
typename VEC>
424 typedef typename gmm::linalg_traits<VEC>::value_type T;
425 return sqrt(asm_H2_semi_norm_sqr(mim, mf, U, rg, T()));
428 template<
typename VEC,
typename T>
429 inline scalar_type asm_H2_semi_norm_sqr
430 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
431 const mesh_region &rg_, T) {
432 ga_workspace workspace;
433 model_real_plain_vector UU(mf.nb_dof()); gmm::copy(U, UU);
434 gmm::sub_interval Iu(0, mf.nb_dof());
435 workspace.add_fem_variable(
"u", mf, Iu, UU);
436 workspace.add_expression(
"Hess_u:Hess_u", mim, rg_);
437 workspace.assembly(0);
438 return workspace.assembled_potential();
441 inline scalar_type asm_H2_semi_norm_sqr
442 (
const mesh_im &mim,
const mesh_fem &mf,
const model_real_plain_vector &U,
443 const mesh_region &rg_, scalar_type) {
444 ga_workspace workspace;
445 gmm::sub_interval Iu(0, mf.nb_dof());
446 workspace.add_fem_variable(
"u", mf, Iu, U);
447 workspace.add_expression(
"Hess_u:Hess_u", mim, rg_);
448 workspace.assembly(0);
449 return workspace.assembled_potential();
453 template<
typename VEC,
typename T>
454 inline scalar_type asm_H2_semi_norm_sqr
455 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
456 const mesh_region &rg, std::complex<T>) {
457 ga_workspace workspace;
458 model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
461 gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
462 workspace.add_fem_variable(
"u", mf, Iur, UUR);
463 workspace.add_fem_variable(
"v", mf, Iui, UUI);
464 workspace.add_expression(
"Hess_u:Hess_u + Hess_v:Hess_v", mim, rg);
465 workspace.assembly(0);
466 return workspace.assembled_potential();
470 template<
typename VEC1,
typename VEC2>
471 inline scalar_type asm_H2_semi_dist
472 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
473 const mesh_fem &mf2,
const VEC2 &U2,
475 return sqrt(asm_H2_semi_dist_sqr(mim, mf1, U1, mf2, U2, rg,
476 typename gmm::linalg_traits<VEC1>::value_type()));
479 template<
typename VEC1,
typename VEC2,
typename T>
480 inline scalar_type asm_H2_semi_dist_sqr
481 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
482 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, T) {
483 ga_workspace workspace;
484 model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
486 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
487 workspace.add_fem_variable(
"u1", mf1, Iu1, UU1);
488 workspace.add_fem_variable(
"u2", mf2, Iu2, UU2);
489 workspace.add_expression(
"(Hess_u2-Hess_u1):(Hess_u2-Hess_u1)", mim, rg);
490 workspace.assembly(0);
491 return workspace.assembled_potential();
494 inline scalar_type asm_H2_semi_dist_sqr
495 (
const mesh_im &mim,
const mesh_fem &mf1,
const model_real_plain_vector &U1,
496 const mesh_fem &mf2,
const model_real_plain_vector &U2,
497 mesh_region rg, scalar_type) {
498 ga_workspace workspace;
499 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
500 workspace.add_fem_variable(
"u1", mf1, Iu1, U1);
501 workspace.add_fem_variable(
"u2", mf2, Iu2, U2);
502 workspace.add_expression(
"(Hess_u2-Hess_u1):(Hess_u2-Hess_u1)", mim, rg);
503 workspace.assembly(0);
504 return workspace.assembled_potential();
507 template<
typename VEC1,
typename VEC2,
typename T>
508 inline scalar_type asm_H2_semi_dist_sqr
509 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
510 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, std::complex<T>) {
511 ga_workspace workspace;
512 model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
513 model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
516 gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
517 gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
518 gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
519 workspace.add_fem_variable(
"u1", mf1, Iu1r, UU1R);
520 workspace.add_fem_variable(
"u2", mf2, Iu2r, UU2R);
521 workspace.add_fem_variable(
"v1", mf1, Iu1i, UU1I);
522 workspace.add_fem_variable(
"v2", mf2, Iu2i, UU2I);
523 workspace.add_expression(
"(Hess_u2-Hess_u1):(Hess_u2-Hess_u1)"
524 "+ (Hess_v2-Hess_v1):(Hess_v2-Hess_v1)", mim, rg);
525 workspace.assembly(0);
526 return workspace.assembled_potential();
533 template<
typename VEC>
538 typedef typename gmm::linalg_traits<VEC>::value_type T;
539 return sqrt(asm_H1_norm_sqr(mim, mf, U, rg, T())
540 + asm_H2_semi_norm_sqr(mim, mf, U, rg, T()));
547 template<
typename VEC1,
typename VEC2>
549 const mesh_fem &mf1,
const VEC1 &U1,
550 const mesh_fem &mf2,
const VEC2 &U2,
553 typedef typename gmm::linalg_traits<VEC1>::value_type T;
554 return sqrt(asm_H1_dist_sqr(mim,mf1,U1,mf2,U2,rg,T()) +
555 asm_H2_semi_dist_sqr(mim,mf1,U1,mf2,U2,rg,T()));
562 template <
typename MAT,
typename VECT>
563 inline void asm_real_or_complex_1_param_mat
564 (MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
const mesh_fem *mf_data,
565 const VECT &A,
const mesh_region &rg,
const char *assembly_description) {
566 asm_real_or_complex_1_param_mat_
567 (M, mim, mf_u, mf_data, A, rg, assembly_description,
568 typename gmm::linalg_traits<VECT>::value_type());
572 template<
typename MAT,
typename VECT,
typename T>
573 inline void asm_real_or_complex_1_param_mat_
574 (
const MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
575 const mesh_fem *mf_data,
const VECT &A,
const mesh_region &rg,
576 const char *assembly_description, T) {
577 ga_workspace workspace;
578 gmm::sub_interval Iu(0, mf_u.nb_dof());
579 base_vector u(mf_u.nb_dof()), AA(gmm::vect_size(A));
581 workspace.add_fem_variable(
"u", mf_u, Iu, u);
583 workspace.add_fem_constant(
"A", *mf_data, AA);
585 workspace.add_fixed_size_constant(
"A", AA);
586 workspace.add_expression(assembly_description, mim, rg);
587 workspace.assembly(2);
588 if (gmm::mat_nrows(workspace.assembled_matrix()))
589 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
592 inline void asm_real_or_complex_1_param_mat_
593 (model_real_sparse_matrix &M,
const mesh_im &mim,
const mesh_fem &mf_u,
594 const mesh_fem *mf_data,
const model_real_plain_vector &A,
595 const mesh_region &rg,
596 const char *assembly_description, scalar_type) {
597 ga_workspace workspace;
598 gmm::sub_interval Iu(0, mf_u.nb_dof());
599 base_vector u(mf_u.nb_dof());
600 workspace.add_fem_variable(
"u", mf_u, Iu, u);
602 workspace.add_fem_constant(
"A", *mf_data, A);
604 workspace.add_fixed_size_constant(
"A", A);
605 workspace.add_expression(assembly_description, mim, rg);
606 workspace.set_assembled_matrix(M);
607 workspace.assembly(2);
611 template<
typename MAT,
typename VECT,
typename T>
612 inline void asm_real_or_complex_1_param_mat_
613 (MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
const mesh_fem *mf_data,
614 const VECT &A,
const mesh_region &rg,
const char *assembly_description,
616 asm_real_or_complex_1_param_mat_(gmm::real_part(M),mim,mf_u,mf_data,
617 gmm::real_part(A),rg,
618 assembly_description, T());
619 asm_real_or_complex_1_param_mat_(gmm::imag_part(M),mim,mf_u,mf_data,
620 gmm::imag_part(A),rg,
621 assembly_description, T());
628 template <
typename MAT,
typename VECT>
629 inline void asm_real_or_complex_1_param_vec
630 (MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
const mesh_fem *mf_data,
631 const VECT &A,
const mesh_region &rg,
const char *assembly_description) {
632 asm_real_or_complex_1_param_vec_
633 (M, mim, mf_u, mf_data, A, rg, assembly_description,
634 typename gmm::linalg_traits<VECT>::value_type());
638 template<
typename VECTA,
typename VECT,
typename T>
639 inline void asm_real_or_complex_1_param_vec_
640 (
const VECTA &V,
const mesh_im &mim,
const mesh_fem &mf_u,
641 const mesh_fem *mf_data,
const VECT &A,
const mesh_region &rg,
642 const char *assembly_description, T) {
643 ga_workspace workspace;
644 gmm::sub_interval Iu(0, mf_u.nb_dof());
645 base_vector u(mf_u.nb_dof()), AA(gmm::vect_size(A));
647 workspace.add_fem_variable(
"u", mf_u, Iu, u);
649 workspace.add_fem_constant(
"A", *mf_data, AA);
651 workspace.add_fixed_size_constant(
"A", AA);
652 workspace.add_expression(assembly_description, mim, rg);
653 workspace.assembly(1);
654 if (gmm::vect_size(workspace.assembled_vector()))
655 gmm::add(workspace.assembled_vector(),
const_cast<VECTA &
>(V));
658 inline void asm_real_or_complex_1_param_vec_
659 (model_real_plain_vector &V,
const mesh_im &mim,
const mesh_fem &mf_u,
660 const mesh_fem *mf_data,
const model_real_plain_vector &A,
661 const mesh_region &rg,
662 const char *assembly_description, scalar_type) {
663 ga_workspace workspace;
664 gmm::sub_interval Iu(0, mf_u.nb_dof());
665 base_vector u(mf_u.nb_dof());
666 workspace.add_fem_variable(
"u", mf_u, Iu, u);
668 workspace.add_fem_constant(
"A", *mf_data, A);
670 workspace.add_fixed_size_constant(
"A", A);
671 workspace.add_expression(assembly_description, mim, rg);
672 workspace.set_assembled_vector(V);
673 workspace.assembly(1);
677 template<
typename MAT,
typename VECT,
typename T>
678 inline void asm_real_or_complex_1_param_vec_
679 (MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
const mesh_fem *mf_data,
680 const VECT &A,
const mesh_region &rg,
const char *assembly_description,
682 asm_real_or_complex_1_param_vec_(gmm::real_part(M),mim,mf_u,mf_data,
683 gmm::real_part(A),rg,
684 assembly_description, T());
685 asm_real_or_complex_1_param_vec_(gmm::imag_part(M),mim,mf_u,mf_data,
686 gmm::imag_part(A),rg,
687 assembly_description, T());
695 template<
typename MAT>
700 ga_workspace workspace;
701 gmm::sub_interval Iu1(0, mf1.
nb_dof());
702 base_vector u1(mf1.
nb_dof());
703 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
704 workspace.add_expression(
"Test_u1:Test2_u1", mim, rg);
705 workspace.assembly(2);
706 if (gmm::mat_nrows(workspace.assembled_matrix()))
707 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
711 (model_real_sparse_matrix &M,
const mesh_im &mim,
714 ga_workspace workspace;
715 gmm::sub_interval Iu1(0, mf1.nb_dof());
716 base_vector u1(mf1.nb_dof());
717 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
718 workspace.add_expression(
"Test_u1:Test2_u1", mim, rg);
719 workspace.set_assembled_matrix(M);
720 workspace.assembly(2);
728 template<
typename MAT>
732 ga_workspace workspace;
733 gmm::sub_interval Iu1(0, mf1.
nb_dof()), Iu2(Iu1.last(), mf2.
nb_dof());
735 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
736 workspace.add_fem_variable(
"u2", mf2, Iu2, u2);
737 workspace.add_expression(
"Test_u1:Test2_u2", mim, rg);
738 workspace.assembly(2);
739 if (gmm::mat_nrows(workspace.assembled_matrix()))
740 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(), Iu1, Iu2),
741 const_cast<MAT &
>(M));
745 (model_real_sparse_matrix &M,
const mesh_im &mim,
746 const mesh_fem &mf1,
const mesh_fem &mf2,
748 ga_workspace workspace;
749 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(0, mf2.nb_dof());
750 base_vector u1(mf1.nb_dof()), u2(mf2.nb_dof());
751 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
752 workspace.add_fem_variable(
"u2", mf2, Iu2, u2);
753 workspace.add_expression(
"Test_u1:Test2_u2", mim, rg);
754 workspace.set_assembled_matrix(M);
755 workspace.assembly(2);
763 template<
typename MAT,
typename VECT>
766 const mesh_fem &mf_data,
const VECT &A,
769 ga_workspace workspace;
770 gmm::sub_interval Iu1(0, mf1.
nb_dof()), Iu2(Iu1.last(), mf2.
nb_dof());
773 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
774 workspace.add_fem_variable(
"u2", mf2, Iu2, u2);
775 workspace.add_fem_constant(
"A", mf_data, AA);
776 workspace.add_expression(
"(A*Test_u1).Test2_u2", mim, rg);
777 workspace.assembly(2);
778 if (gmm::mat_nrows(workspace.assembled_matrix()))
779 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(), Iu1, Iu2),
780 const_cast<MAT &
>(M));
784 (model_real_sparse_matrix &M,
const mesh_im &mim,
785 const mesh_fem &mf1,
const mesh_fem &mf2,
786 const mesh_fem &mf_data,
const model_real_plain_vector &A,
789 ga_workspace workspace;
790 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(0, mf2.nb_dof());
791 base_vector u1(mf1.nb_dof()), u2(mf2.nb_dof());
792 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
793 workspace.add_fem_variable(
"u2", mf2, Iu2, u2);
794 workspace.add_fem_constant(
"A", mf_data, A);
795 workspace.add_expression(
"(A*Test_u1).Test2_u2", mim, rg);
796 workspace.set_assembled_matrix(M);
797 workspace.assembly(2);
807 template<
typename MAT,
typename VECT>
811 asm_real_or_complex_1_param_mat
812 (M, mim, mf_u, &mf_data, F, rg,
"(A*Test_u):Test2_u");
820 template<
typename MAT,
typename VECT>
824 asm_real_or_complex_1_param_mat
825 (M, mim, mf_u, 0, F, rg,
"(A*Test_u):Test2_u");
831 template<
typename MAT>
834 size_type nbd = gmm::mat_ncols(M), nbr = gmm::mat_nrows(M);
835 GMM_ASSERT1(nbd == nbr,
"mass matrix is not square");
836 typedef typename gmm::linalg_traits<MAT>::value_type T;
837 std::vector<T> V(nbd), W(nbr);
840 gmm::clear(
const_cast<MAT &
>(M));
842 (
const_cast<MAT &
>(M))(i, i) = W[i];
851 template<
typename MAT>
864 template<
typename MAT,
typename VECT>
876 template<
typename VECT1,
typename VECT2>
878 const mesh_fem &mf_data,
const VECT2 &F,
880 GMM_ASSERT1(mf_data.
get_qdim() == 1 ||
882 "invalid data mesh fem (same Qdim or Qdim=1 required)");
883 asm_real_or_complex_1_param_vec
884 (
const_cast<VECT1 &
>(B), mim, mf, &mf_data, F, rg,
"A:Test_u");
892 template<
typename VECT1,
typename VECT2>
896 asm_real_or_complex_1_param_vec
897 (
const_cast<VECT1 &
>(B), mim, mf, 0, F, rg,
"A:Test_u");
904 template<
typename VECT1,
typename VECT2>
907 const mesh_fem &mf_data,
const VECT2 &F,
909 asm_real_or_complex_1_param_vec(B, mim, mf, &mf_data, F, rg,
910 "(Reshape(A, qdim(u), meshdim).Normal):Test_u");
917 template<
typename VECT1,
typename VECT2>
921 { asm_real_or_complex_1_param_vec(B, mim, mf, 0,F,rg,
922 "(Reshape(A, qdim(u), meshdim).Normal):Test_u"); }
943 template<
typename MAT,
typename VECT>
945 const mesh_fem &mf_d,
const VECT &Q,
948 asm_real_or_complex_1_param_mat
949 (M, mim,mf_u,&mf_d,Q,rg,
"(Reshape(A,qdim(u),qdim(u)).Test_u):Test2_u");
951 asm_real_or_complex_1_param_mat
952 (M, mim, mf_u, &mf_d, Q, rg,
"(A*Test_u):Test2_u");
953 else GMM_ASSERT1(
false,
"invalid data mesh fem");
956 template<
typename MAT,
typename VECT>
957 void asm_homogeneous_qu_term(MAT &M,
const mesh_im &mim,
958 const mesh_fem &mf_u,
const VECT &Q,
959 const mesh_region &rg) {
960 if (gmm::vect_size(Q) == 1)
961 asm_real_or_complex_1_param_mat
962 (M, mim,mf_u,0,Q,rg,
"(A*Test_u):Test2_u");
964 asm_real_or_complex_1_param_mat
965 (M, mim,mf_u,0,Q,rg,
"(Reshape(A,qdim(u),qdim(u)).Test_u):Test2_u");
972 template<
class MAT,
class VECT>
975 const mesh_fem &mf_data,
const VECT &LAMBDA,
const VECT &MU,
977 ga_workspace workspace;
978 gmm::sub_interval Iu(0, mf.
nb_dof());
979 base_vector u(mf.
nb_dof()), lambda(gmm::vect_size(LAMBDA));
980 base_vector mu(gmm::vect_size(MU));
981 gmm::copy(LAMBDA, lambda); gmm::copy(MU, mu);
982 workspace.add_fem_variable(
"u", mf, Iu, u);
983 workspace.add_fem_constant(
"lambda", mf_data, lambda);
984 workspace.add_fem_constant(
"mu", mf_data, mu);
985 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)"
986 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
987 workspace.assembly(2);
988 if (gmm::mat_nrows(workspace.assembled_matrix()))
989 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
993 (model_real_sparse_matrix &M,
const mesh_im &mim,
const mesh_fem &mf,
994 const mesh_fem &mf_data,
const model_real_plain_vector &LAMBDA,
995 const model_real_plain_vector &MU,
997 ga_workspace workspace;
998 gmm::sub_interval Iu(0, mf.nb_dof());
999 base_vector u(mf.nb_dof());
1000 workspace.add_fem_variable(
"u", mf, Iu, u);
1001 workspace.add_fem_constant(
"lambda", mf_data, LAMBDA);
1002 workspace.add_fem_constant(
"mu", mf_data, MU);
1003 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)"
1004 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
1005 workspace.set_assembled_matrix(M);
1006 workspace.assembly(2);
1014 template<
class MAT,
class VECT>
1017 const VECT &LAMBDA,
const VECT &MU,
1019 ga_workspace workspace;
1020 gmm::sub_interval Iu(0, mf.
nb_dof());
1021 base_vector u(mf.
nb_dof()), lambda(gmm::vect_size(LAMBDA));
1022 base_vector mu(gmm::vect_size(MU));
1023 gmm::copy(LAMBDA, lambda); gmm::copy(MU, mu);
1024 workspace.add_fem_variable(
"u", mf, Iu, u);
1025 workspace.add_fixed_size_constant(
"lambda", lambda);
1026 workspace.add_fixed_size_constant(
"mu", mu);
1027 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)"
1028 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
1029 workspace.assembly(2);
1030 if (gmm::mat_nrows(workspace.assembled_matrix()))
1031 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
1036 (model_real_sparse_matrix &M,
const mesh_im &mim,
const mesh_fem &mf,
1037 const model_real_plain_vector &LAMBDA,
const model_real_plain_vector &MU,
1039 ga_workspace workspace;
1040 gmm::sub_interval Iu(0, mf.nb_dof());
1041 base_vector u(mf.nb_dof());
1042 workspace.add_fem_variable(
"u", mf, Iu, u);
1043 workspace.add_fixed_size_constant(
"lambda", LAMBDA);
1044 workspace.add_fixed_size_constant(
"mu", MU);
1045 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)"
1046 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
1047 workspace.set_assembled_matrix(M);
1048 workspace.assembly(2);
1061 template<
typename MAT,
typename VECT>
void
1073 template<
typename MAT>
1077 ga_workspace workspace;
1078 gmm::sub_interval Iu(0, mf_u.
nb_dof()), Ip(Iu.last(), mf_p.
nb_dof());
1080 workspace.add_fem_variable(
"u", mf_u, Iu, u);
1081 workspace.add_fem_variable(
"p", mf_p, Ip, p);
1082 workspace.add_expression(
"Test_p*Div_Test2_u", mim, rg);
1083 workspace.assembly(2);
1084 if (gmm::mat_nrows(workspace.assembled_matrix()))
1085 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(), Ip, Iu),
1086 const_cast<MAT &
>(B));
1089 inline void asm_stokes_B(model_real_sparse_matrix &B,
const mesh_im &mim,
1090 const mesh_fem &mf_u,
const mesh_fem &mf_p,
1092 ga_workspace workspace;
1093 gmm::sub_interval Iu(0, mf_u.nb_dof()), Ip(0, mf_p.nb_dof());
1094 base_vector u(mf_u.nb_dof()), p(mf_p.nb_dof());
1095 workspace.add_fem_variable(
"u", mf_u, Iu, u);
1096 workspace.add_fem_variable(
"p", mf_p, Ip, p);
1097 workspace.add_expression(
"Test_p*Div_Test2_u", mim, rg);
1098 workspace.set_assembled_matrix(B);
1099 workspace.assembly(2);
1108 template<
typename MAT>
1112 ga_workspace workspace;
1113 gmm::sub_interval Iu(0, mf.
nb_dof());
1114 base_vector u(mf.
nb_dof());
1115 workspace.add_fem_variable(
"u", mf, Iu, u);
1116 workspace.add_expression(
"Grad_Test_u:Grad_Test2_u", mim, rg);
1117 workspace.assembly(2);
1118 if (gmm::mat_nrows(workspace.assembled_matrix()))
1119 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
1123 (model_real_sparse_matrix &M,
const mesh_im &mim,
const mesh_fem &mf,
1125 ga_workspace workspace;
1126 gmm::sub_interval Iu(0, mf.nb_dof());
1127 base_vector u(mf.nb_dof());
1128 workspace.add_fem_variable(
"u", mf, Iu, u);
1129 workspace.add_expression(
"Grad_Test_u:Grad_Test2_u", mim, rg);
1130 workspace.set_assembled_matrix(M);
1131 workspace.assembly(2);
1138 template<
typename MAT>
1150 template<
typename MAT,
typename VECT>
1154 GMM_ASSERT1(mf_data.
get_qdim() == 1
1155 && gmm::vect_size(A) == mf_data.
nb_dof(),
"invalid data");
1156 asm_real_or_complex_1_param_mat
1157 (M, mim, mf, &mf_data, A, rg,
"(A*Grad_Test_u):Grad_Test2_u");
1163 template<
typename MAT,
typename VECT>
1193 template<
typename MAT,
typename VECT>
1197 asm_real_or_complex_1_param_mat
1198 (M, mim, mf, &mf_data, A, rg,
1199 "(Reshape(A,meshdim,meshdim)*Grad_Test_u):Grad_Test2_u");
1204 template<
typename MAT,
typename VECT>
1208 asm_real_or_complex_1_param_mat
1209 (M, mim, mf, 0, A, rg,
1210 "(Reshape(A,meshdim,meshdim)*Grad_Test_u):Grad_Test2_u");
1215 template<
typename MAT,
typename VECT>
1218 const mesh_fem &mf_data,
const VECT &A,
1220 asm_real_or_complex_1_param_mat
1221 (M, mim, mf, &mf_data, A, rg,
1222 "(Grad_Test_u*(Reshape(A,meshdim,meshdim)')):Grad_Test2_u");
1227 template<
typename MAT,
typename VECT>
1231 asm_real_or_complex_1_param_mat
1232 (M, mim, mf, 0, A, rg,
1233 "(Grad_Test_u*(Reshape(A,meshdim,meshdim)')):Grad_Test2_u");
1241 template<
typename MAT,
typename VECT>
void
1246 asm_real_or_complex_1_param_mat
1247 (M, mim, mf, &mf_data, A, rg,
1248 "(Reshape(A,qdim(u),meshdim,qdim(u),meshdim):Grad_Test_u):Grad_Test2_u");
1255 template<
typename MAT,
typename VECT>
void
1260 asm_real_or_complex_1_param_mat
1261 (M, mim, mf, 0, A, rg,
1262 "(Reshape(A,qdim(u),meshdim,qdim(u),meshdim):Grad_Test_u):Grad_Test2_u");
1273 template<
typename MAT,
typename VECT>
1275 const mesh_fem &mf_data,
const VECT &K_squared,
1277 typedef typename gmm::linalg_traits<MAT>::value_type T;
1278 asm_Helmholtz_(M, mim, mf_u, &mf_data, K_squared, rg, T());
1281 template<
typename MAT,
typename VECT,
typename T>
1282 void asm_Helmholtz_(MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
1283 const mesh_fem *mf_data,
const VECT &K_squared,
1284 const mesh_region &rg, T) {
1285 asm_real_or_complex_1_param_mat
1286 (M, mim, mf_u, mf_data, K_squared, rg,
1287 "(A*Test_u).Test2_u - Grad_Test_u:Grad_Test2_u");
1290 template<
typename MAT,
typename VECT,
typename T>
1291 void asm_Helmholtz_(MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
1292 const mesh_fem *mf_data,
const VECT &K_squared,
1293 const mesh_region &rg, std::complex<T>) {
1302 ga_workspace workspace;
1303 gmm::sub_interval Iur(0, mf_u.nb_dof()), Iui(Iur.last(), mf_u.nb_dof());
1304 base_vector u(mf_u.nb_dof());
1305 base_vector AR(gmm::vect_size(K_squared)), AI(gmm::vect_size(K_squared));
1306 gmm::copy(gmm::real_part(K_squared), AR);
1307 gmm::copy(gmm::imag_part(K_squared), AI);
1308 workspace.add_fem_variable(
"u", mf_u, Iur, u);
1309 workspace.add_fem_variable(
"ui", mf_u, Iui, u);
1312 workspace.add_fem_constant(
"A", *mf_data, AR);
1313 workspace.add_fem_constant(
"AI", *mf_data, AI);
1315 workspace.add_fixed_size_constant(
"A", AR);
1316 workspace.add_fixed_size_constant(
"AI", AI);
1318 workspace.add_expression(
"(A*Test_u).Test2_u - Grad_Test_u:Grad_Test2_u",
1320 workspace.add_expression(
"(AI*Test_ui).Test2_ui", mim, rg);
1321 workspace.assembly(2);
1323 if (gmm::mat_nrows(workspace.assembled_matrix()))
1324 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(),Iur,Iur),
1325 const_cast<MAT &
>(M));
1326 if (gmm::mat_nrows(workspace.assembled_matrix()) > mf_u.nb_dof())
1327 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(),Iui,Iui),
1328 gmm::imag_part(
const_cast<MAT &
>(M)));
1342 template<
typename MAT,
typename VECT>
1344 (MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
const VECT &K_squared,
1346 typedef typename gmm::linalg_traits<MAT>::value_type T;
1347 asm_Helmholtz_(M, mim, mf_u, 0, K_squared, rg, T());
1350 enum { ASMDIR_BUILDH = 1, ASMDIR_BUILDR = 2, ASMDIR_SIMPLIFY = 4,
1351 ASMDIR_BUILDALL = 7 };
1371 template<
typename MAT,
typename VECT1,
typename VECT2>
1376 int version = ASMDIR_BUILDALL) {
1377 typedef typename gmm::linalg_traits<VECT1>::value_type value_type;
1378 typedef typename gmm::number_traits<value_type>::magnitude_type magn_type;
1380 if ((version & ASMDIR_SIMPLIFY) &&
1382 GMM_WARNING1(
"Sorry, no simplification for reduced fems");
1383 version = (version & (ASMDIR_BUILDR | ASMDIR_BUILDH));
1388 "invalid data mesh fem (Qdim=1 required)");
1389 if (version & ASMDIR_BUILDH) {
1391 gmm::clean(H, gmm::default_tol(magn_type())
1392 * gmm::mat_maxnorm(H) * magn_type(1000));
1394 if (version & ASMDIR_BUILDR)
1399 pfem pf_u, pf_r, pf_m;
1400 bool warning_msg1 =
false, warning_msg2 =
false;
1401 dal::bit_vector simplifiable_dofs, nonsimplifiable_dofs;
1402 std::vector<size_type> simplifiable_indices(mf_mult.
nb_basic_dof());
1403 std::vector<value_type> simplifiable_values(mf_mult.
nb_basic_dof());
1404 std::vector<value_type> v1, v2, v3;
1406 for (
mr_visitor v(region); !v.finished(); v.next()) {
1407 GMM_ASSERT1(v.is_face(),
"attempt to impose a dirichlet "
1408 "on the interior of the domain!");
1414 "attempt to impose a dirichlet "
1415 "condition on a convex with no FEM!");
1420 if (!pf_m->is_lagrange() && !warning_msg1) {
1421 GMM_WARNING3(
"Dirichlet condition with non-lagrange multiplier fem. "
1422 "see the documentation about Dirichlet conditions.");
1423 warning_msg1 =
true;
1426 if (!(version & ASMDIR_SIMPLIFY))
continue;
1428 mesh_fem::ind_dof_face_ct pf_u_ct
1430 mesh_fem::ind_dof_face_ct pf_r_ct
1432 mesh_fem::ind_dof_face_ct pf_m_ct
1437 size_type pf_u_nbdf_loc = pf_u->structure(cv)->nb_points_of_face(f);
1438 size_type pf_m_nbdf_loc = pf_m->structure(cv)->nb_points_of_face(f);
1441 if (pf_u_nbdf < pf_m_nbdf && !warning_msg2) {
1442 GMM_WARNING2(
"Dirichlet condition with a too rich multiplier fem. "
1443 "see the documentation about Dirichlet conditions.");
1444 warning_msg2 =
true;
1447 if (pf_u != pf_r || pf_u_nbdf != pf_m_nbdf ||
1448 ((pf_u != pf_r) && (pf_u_nbdf_loc != pf_m_nbdf_loc))) {
1449 for (
size_type i = 0; i < pf_m_nbdf; ++i)
1450 nonsimplifiable_dofs.add(pf_m_ct[i]);
1454 for (
size_type i = 0; i < pf_m_nbdf; ++i) {
1455 simplifiable_dofs.add(pf_m_ct[i]);
1456 simplifiable_indices[pf_m_ct[i]] = pf_u_ct[i];
1459 if (!(version & ASMDIR_BUILDR))
continue;
1463 for (
size_type i = 0; i < pf_m_nbdf; ++i) {
1464 simplifiable_values[pf_m_ct[i]]
1465 = r_data[pf_r_ct[i/Qratio]*Qratio+(i%Qratio)];
1470 if (version & ASMDIR_SIMPLIFY) {
1471 if (simplifiable_dofs.card() > 0)
1472 { GMM_TRACE3(
"Simplification of the Dirichlet condition"); }
1474 GMM_TRACE3(
"Sorry, no simplification of the Dirichlet condition");
1475 if (nonsimplifiable_dofs.card() > 0 && simplifiable_dofs.card() > 0)
1476 GMM_WARNING3(
"Partial simplification of the Dirichlet condition");
1478 for (dal::bv_visitor i(simplifiable_dofs); !i.finished(); ++i)
1479 if (!(nonsimplifiable_dofs[i])) {
1480 if (version & ASMDIR_BUILDH) {
1482 for (
size_type j = 0; j < cv_ct.size(); ++j) {
1487 H(i, simplifiable_indices[i]) = value_type(1);
1489 if (version & ASMDIR_BUILDR) R[i] = simplifiable_values[i];
1494 template<
typename MATRM,
typename VECT1,
typename VECT2>
1495 void assembling_Dirichlet_condition
1500 GMM_ASSERT1(!(mf.
is_reduced()),
"This function is not adapted to "
1501 "reduced finite element methods");
1504 for (dal::bv_visitor cv(mf.
convex_index()); !cv.finished(); ++cv) {
1510 if (nndof.is_in(dof1) && pf1->dof_types()[i] == ldof) {
1516 if (!(nndof.is_in(dof2)) &&
1519 B[dof2+k] -= RM(dof2+k, dof1+l) * F[dof1+l];
1520 RM(dof2+k, dof1+l) = RM(dof1+l, dof2+k) = 0;
1524 { RM(dof1+k, dof1+k) = 1; B[dof1+k] = F[dof1+k]; }
1548 template<
typename MAT,
typename VECT1,
typename VECT2,
typename VECT3>
1553 int version = ASMDIR_BUILDALL) {
1556 if ((version & ASMDIR_SIMPLIFY) &&
1558 GMM_WARNING1(
"Sorry, no simplification for reduced fems");
1559 version = (version & ASMDIR_BUILDR);
1564 "invalid data mesh fem (Qdim=1 required)");
1565 if (version & ASMDIR_BUILDH) {
1567 std::vector<size_type> ind(0);
1571 if (!(bdof[i])) ind.push_back(i);
1572 gmm::clear(gmm::sub_matrix(H, gmm::sub_index(ind)));
1574 if (version & ASMDIR_BUILDR)
1576 if (!(version & ASMDIR_SIMPLIFY))
return;
1579 if (&mf_r == &mf_h) {
1580 for (
mr_visitor v(region); !v.finished(); v.next()) {
1586 "attempt to impose a dirichlet "
1587 "condition on a convex with no FEM!");
1597 for (
size_type i = 0; i < cvs_u->nb_points_of_face(f); ++i) {
1601 size_type ind_u = cvs_u->ind_points_of_face(f)[i];
1604 for (
size_type j = 0; j < cvs_rh->nb_points_of_face(f); ++j) {
1605 size_type ind_rh = cvs_rh->ind_points_of_face(f)[j];
1617 if (tdof_u == tdof_rh &&
1618 gmm::vect_dist2_sqr((*(pf_u->node_tab(cv)))[ind_u],
1619 (*(pf_rh->node_tab(cv)))[ind_rh])
1626 if (version & ASMDIR_BUILDH)
1632 if (version & ASMDIR_BUILDH)
1633 for (
unsigned jj=0; jj < Q; jj++) {
1636 H(dof_u, dof_u2) = h_data[(jj*Q+q) + Q*Q*(dof_rh)];
1638 if (version & ASMDIR_BUILDR) R[dof_u] = r_data[dof_rh*Q+q];
1655 template<
typename MAT1,
typename MAT2,
typename VECT1,
typename VECT2>
1657 const VECT1 &R, VECT2 &U0) {
1659 typedef typename gmm::linalg_traits<MAT1>::value_type T;
1660 typedef typename gmm::number_traits<T>::magnitude_type MAGT;
1661 typedef typename gmm::temporary_vector<MAT1>::vector_type TEMP_VECT;
1662 MAGT tol = gmm::default_tol(MAGT());
1663 MAGT norminfH = gmm::mat_maxnorm(H);
1664 size_type nbd = gmm::mat_ncols(H), nbase = 0, nbr = gmm::mat_nrows(H);
1665 TEMP_VECT aux(nbr), e(nbd), f(nbd);
1671 if (!(gmm::is_col_matrix(H)))
1672 GMM_WARNING2(
"Dirichlet_nullspace inefficient for a row matrix H");
1677 gmm::clear(e); e[i] = T(1);
1678 gmm::mult(H, e, aux);
1679 MAGT n = gmm::vect_norm2(aux);
1681 if (n < norminfH*tol*1000) {
1682 NS(i, nbase++) = T(1); nn[i] =
true;
1687 if (gmm::abs(gmm::vect_sp(aux, base_img[j])) > MAGT(0))
1688 { good =
false;
break; }
1691 gmm::scale(f, T(MAGT(1)/n)); gmm::scale(aux, T(MAGT(1)/n));
1692 base_img_inv[nb_bimg] = TEMP_VECT(nbd);
1693 gmm::copy(f, base_img_inv[nb_bimg]);
1694 gmm::clean(aux, gmm::vect_norminf(aux)*tol);
1695 base_img[nb_bimg] = TEMP_VECT(nbr);
1696 gmm::copy(aux, base_img[nb_bimg++]);
1705 gmm::clear(e); e[i] = T(1); gmm::clear(f); f[i] = T(1);
1706 gmm::mult(H, e, aux);
1707 for (
size_type j = 0; j < nb_bimg; ++j) {
1708 T c = gmm::vect_sp(aux, base_img[j]);
1711 gmm::add(gmm::scaled(base_img[j], -c), aux);
1712 gmm::add(gmm::scaled(base_img_inv[j], -c), f);
1715 if (gmm::vect_norm2(aux) < norminfH*tol*MAGT(10000)) {
1716 gmm::copy(f, gmm::mat_col(NS, nbase++));
1719 MAGT n = gmm::vect_norm2(aux);
1720 gmm::scale(f, T(MAGT(1)/n)); gmm::scale(aux, T(MAGT(1)/n));
1721 gmm::clean(f, tol*gmm::vect_norminf(f));
1722 gmm::clean(aux, tol*gmm::vect_norminf(aux));
1723 base_img_inv[nb_bimg] = TEMP_VECT(nbd);
1724 gmm::copy(f, base_img_inv[nb_bimg]);
1725 base_img[nb_bimg] = TEMP_VECT(nbr);
1726 gmm::copy(aux, base_img[nb_bimg++]);
1732 for (
size_type i = 0; i < nb_bimg; ++i) {
1733 T c = gmm::vect_sp(base_img[i], R);
1734 gmm::add(gmm::scaled(base_img_inv[i], c), U0);
1737 for (
size_type i = nb_triv_base; i < nbase; ++i) {
1738 for (
size_type j = nb_triv_base; j < i; ++j) {
1739 T c = gmm::vect_sp(gmm::mat_col(NS,i), gmm::mat_col(NS,j));
1741 gmm::add(gmm::scaled(gmm::mat_col(NS,j), -c), gmm::mat_col(NS,i));
1743 gmm::scale(gmm::mat_col(NS,i),
1744 T(1) / gmm::vect_norm2(gmm::mat_col(NS,i)));
1747 for (
size_type j = nb_triv_base; j < nbase; ++j) {
1748 T c = gmm::vect_sp(gmm::mat_col(NS,j), U0);
1750 gmm::add(gmm::scaled(gmm::mat_col(NS,j), -c), U0);
1753 gmm::mult(H, U0, gmm::scaled(R, T(-1)), aux);
1754 if (gmm::vect_norm2(aux) > gmm::vect_norm2(U0)*tol*MAGT(10000))
1755 GMM_WARNING2(
"Dirichlet condition not well inverted: residu="
1756 << gmm::vect_norm2(aux));
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
Describe a finite element method linked to a mesh.
virtual ind_dof_ct ind_basic_dof_of_element(size_type cv) const
Give an array of the dof numbers a of convex.
virtual dim_type get_qdim() const
Return the Q dimension.
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
virtual size_type nb_basic_dof() const
Return the total number of basic degrees of freedom (before the optional reduction).
virtual dal::bit_vector basic_dof_on_region(const mesh_region &b) const
Get a list of basic dof lying on a given mesh_region.
virtual ind_dof_face_ct ind_basic_dof_of_face_of_element(size_type cv, short_type f) const
Give an array of the dof numbers lying of a convex face (all degrees of freedom whose associated base...
virtual pfem fem_of_element(size_type cv) const
Return the basic fem associated with an element (if no fem is associated, the function will crash!...
const dal::bit_vector & convex_index() const
Get the set of convexes where a finite element has been assigned.
virtual size_type nb_basic_dof_of_element(size_type cv) const
Return the number of degrees of freedom attached to a given convex.
bool is_reduced() const
Return true if a reduction matrix is applied to the dofs.
virtual const mesh::ind_cv_ct & convex_to_basic_dof(size_type d) const
Return the list of convexes attached to the specified dof.
Describe an integration method linked to a mesh.
const mesh & linked_mesh() const
Give a reference to the linked mesh of type mesh.
"iterator" class for regions.
structure used to hold a set of convexes and/or convex faces.
const mesh_region & from_mesh(const mesh &m) const
For regions which have been built with just a number 'id', from_mesh(m) sets the current region to 'm...
static mesh_region all_convexes()
provide a default value for the mesh_region parameters of assembly procedures etc.
Generic assembly implementation.
A language for generic assembly of pde boundary value problems.
void copy(const L1 &l1, L2 &l2)
*/
void add(const L1 &l1, L2 &l2)
*/
scalar_type asm_H2_dist(const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1, const mesh_fem &mf2, const VEC2 &U2, const mesh_region &rg=mesh_region::all_convexes())
Compute the H2 distance between U1 and U2.
scalar_type asm_L2_dist(const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1, const mesh_fem &mf2, const VEC2 &U2, mesh_region rg=mesh_region::all_convexes())
Compute the distance between U1 and U2, defined on two different mesh_fems (but sharing the same mesh...
void asm_stiffness_matrix_for_homogeneous_linear_elasticity(const MAT &M, const mesh_im &mim, const mesh_fem &mf, const VECT &LAMBDA, const VECT &MU, const mesh_region &rg=mesh_region::all_convexes())
Stiffness matrix for linear elasticity, with constant Lamé coefficients.
void asm_mass_matrix(const MAT &M, const mesh_im &mim, const mesh_fem &mf1, const mesh_region &rg=mesh_region::all_convexes())
generic mass matrix assembly (on the whole mesh or on the specified convex set or boundary)
scalar_type asm_H2_norm(const mesh_im &mim, const mesh_fem &mf, const VEC &U, const mesh_region &rg=mesh_region::all_convexes())
compute the H2 norm of U (for C^1 elements).
void asm_stiffness_matrix_for_homogeneous_laplacian(const MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_region &rg=mesh_region::all_convexes())
assembly of .
void asm_stiffness_matrix_for_laplacian(MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT &A, const mesh_region &rg=mesh_region::all_convexes())
assembly of , where is scalar.
void asm_stiffness_matrix_for_scalar_elliptic(MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT &A, const mesh_region &rg=mesh_region::all_convexes())
assembly of , where is a (symmetric positive definite) NxN matrix.
size_type Dirichlet_nullspace(const MAT1 &H, MAT2 &NS, const VECT1 &R, VECT2 &U0)
Build an orthogonal basis of the kernel of H in NS, gives the solution of minimal norm of H*U = R in ...
void asm_stiffness_matrix_for_linear_elasticity(const MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT &LAMBDA, const VECT &MU, const mesh_region &rg=mesh_region::all_convexes())
Stiffness matrix for linear elasticity, with Lamé coefficients.
void asm_source_term(const VECT1 &B, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT2 &F, const mesh_region &rg=mesh_region::all_convexes())
source term (for both volumic sources and boundary (Neumann) sources).
void asm_mass_matrix_homogeneous_param(MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const VECT &F, const mesh_region &rg=mesh_region::all_convexes())
generic mass matrix assembly with an additional constant parameter (on the whole mesh or on the speci...
scalar_type asm_L2_norm(const mesh_im &mim, const mesh_fem &mf, const VEC &U, const mesh_region &rg=mesh_region::all_convexes())
compute , U might be real or complex
void asm_homogeneous_normal_source_term(VECT1 &B, const mesh_im &mim, const mesh_fem &mf, const VECT2 &F, const mesh_region &rg)
Homogeneous normal source term (for boundary (Neumann) condition).
void asm_homogeneous_Helmholtz(MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const VECT &K_squared, const mesh_region &rg=mesh_region::all_convexes())
assembly of the term , for the helmholtz equation ( , with ).
void asm_lumped_mass_matrix_for_first_order_param(MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_data, const VECT &F, const mesh_region &rg=mesh_region::all_convexes())
lumped mass matrix assembly with an additional parameter (on the whole mesh or on the specified bound...
scalar_type asm_H1_norm(const mesh_im &mim, const mesh_fem &mf, const VEC &U, const mesh_region &rg=mesh_region::all_convexes())
compute the H1 norm of U.
void asm_Helmholtz(MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_data, const VECT &K_squared, const mesh_region &rg=mesh_region::all_convexes())
assembly of the term , for the helmholtz equation ( , with ).
scalar_type asm_H1_semi_dist(const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1, const mesh_fem &mf2, const VEC2 &U2, mesh_region rg=mesh_region::all_convexes())
Compute the H1 semi-distance between U1 and U2, defined on two different mesh_fems (but sharing the s...
scalar_type asm_H1_semi_norm(const mesh_im &mim, const mesh_fem &mf, const VEC &U, const mesh_region &rg=mesh_region::all_convexes())
compute , U might be real or complex
void asm_stiffness_matrix_for_homogeneous_laplacian_componentwise(const MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_region &rg=mesh_region::all_convexes())
assembly of .
void asm_stiffness_matrix_for_linear_elasticity_Hooke(MAT &RM, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT &H, const mesh_region &rg=mesh_region::all_convexes())
Stiffness matrix for linear elasticity, with a general Hooke tensor.
void asm_dirichlet_constraints(MAT &H, VECT1 &R, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_mult, const mesh_fem &mf_r, const VECT2 &r_data, const mesh_region ®ion, int version=ASMDIR_BUILDALL)
Assembly of Dirichlet constraints in a weak form.
scalar_type asm_H1_dist(const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1, const mesh_fem &mf2, const VEC2 &U2, mesh_region rg=mesh_region::all_convexes())
Compute the H1 distance between U1 and U2.
scalar_type asm_H2_semi_norm(const mesh_im &mim, const mesh_fem &mf, const VEC &U, const mesh_region &rg=mesh_region::all_convexes())
compute , U might be real or complex.
void asm_normal_source_term(VECT1 &B, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT2 &F, const mesh_region &rg)
Normal source term (for boundary (Neumann) condition).
void asm_stokes_B(const MAT &B, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_p, const mesh_region &rg=mesh_region::all_convexes())
Build the mixed pressure term .
void asm_lumped_mass_matrix_for_first_order(const MAT &M, const mesh_im &mim, const mesh_fem &mf1, const mesh_region &rg=mesh_region::all_convexes())
lumped mass matrix assembly (on the whole mesh or on the specified boundary)
void asm_mass_matrix_param(const MAT &M, const mesh_im &mim, const mesh_fem &mf1, const mesh_fem &mf2, const mesh_fem &mf_data, const VECT &A, const mesh_region &rg=mesh_region::all_convexes())
generic mass matrix assembly with an additional parameter (on the whole mesh or on the specified boun...
void asm_generalized_dirichlet_constraints(MAT &H, VECT1 &R, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_h, const mesh_fem &mf_r, const VECT2 &h_data, const VECT3 &r_data, const mesh_region ®ion, int version=ASMDIR_BUILDALL)
Assembly of generalized Dirichlet constraints h(x)u(x) = r(x), where h is a QxQ matrix field (Q == mf...
void asm_homogeneous_source_term(const VECT1 &B, const mesh_im &mim, const mesh_fem &mf, const VECT2 &F, const mesh_region &rg=mesh_region::all_convexes())
source term (for both volumic sources and boundary (Neumann) sources).
void asm_qu_term(MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_d, const VECT &Q, const mesh_region &rg)
assembly of
bool dof_compatibility(pdof_description, pdof_description)
Says if the two dofs can be identified.
pdof_description lagrange_dof(dim_type d)
Description of a unique dof of lagrange type (value at the node).
dof_description * pdof_description
Type representing a pointer on a dof_description.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
gmm::uint16_type short_type
used as the common short type integer in the library
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
size_t size_type
used as the common size type in the library
GEneric Tool for Finite Element Methods.
void asm_lumped_mass_matrix_for_first_order_from_consistent(const MAT &M)
lumped mass matrix assembly from consistent mass matrix
void asm_stiffness_matrix_for_homogeneous_scalar_elliptic_componentwise(MAT &M, const mesh_im &mim, const mesh_fem &mf, const VECT &A, const mesh_region &rg=mesh_region::all_convexes())
The same but with a constant matrix.
void asm_stiffness_matrix_for_scalar_elliptic_componentwise(MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT &A, const mesh_region &rg=mesh_region::all_convexes())
The same but on each component of mf when mf has a qdim > 1.
void asm_stiffness_matrix_for_vector_elliptic(MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT &A, const mesh_region &rg=mesh_region::all_convexes())
Assembly of , where is a NxNxQxQ (symmetric positive definite) tensor defined on mf_data.
void asm_stiffness_matrix_for_laplacian_componentwise(MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, const VECT &A, const mesh_region &rg=mesh_region::all_convexes())
The same as getfem::asm_stiffness_matrix_for_laplacian , but on each component of mf when mf has a qd...
void asm_stiffness_matrix_for_homogeneous_scalar_elliptic(MAT &M, const mesh_im &mim, const mesh_fem &mf, const VECT &A, const mesh_region &rg=mesh_region::all_convexes())
The same but with a constant matrix.
void asm_stiffness_matrix_for_homogeneous_vector_elliptic(MAT &M, const mesh_im &mim, const mesh_fem &mf, const VECT &A, const mesh_region &rg=mesh_region::all_convexes())
Assembly of , where is a NxNxQxQ (symmetric positive definite) constant tensor.