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
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,
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,
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,
96 ga_workspace workspace;
97 model_real_plain_vector UUR(mf.
nb_dof()), UUI(mf.
nb_dof());
98 gmm::copy(gmm::real_part(U), UUR);
99 gmm::copy(gmm::imag_part(U), UUI);
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
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);
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,
142 ga_workspace workspace;
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
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());
158 gmm::copy(gmm::real_part(U1), UU1R); gmm::copy(gmm::imag_part(U1), UU1I);
159 gmm::copy(gmm::real_part(U2), UU2R); gmm::copy(gmm::imag_part(U2), UU2I);
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
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,
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
214 ga_workspace workspace;
215 model_real_plain_vector UUR(mf.
nb_dof()), UUI(mf.
nb_dof());
216 gmm::copy(gmm::real_part(U), UUR);
217 gmm::copy(gmm::imag_part(U), UUI);
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
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);
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,
260 ga_workspace workspace;
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
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());
276 gmm::copy(gmm::real_part(U1), UU1R); gmm::copy(gmm::imag_part(U1), UU1I);
277 gmm::copy(gmm::real_part(U2), UU2R); gmm::copy(gmm::imag_part(U2), UU2I);
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
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,
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
337 ga_workspace workspace;
338 model_real_plain_vector UUR(mf.
nb_dof()), UUI(mf.
nb_dof());
339 gmm::copy(gmm::real_part(U), UUR);
340 gmm::copy(gmm::imag_part(U), UUI);
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
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);
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,
382 ga_workspace workspace;
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
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());
399 gmm::copy(gmm::real_part(U1), UU1R); gmm::copy(gmm::imag_part(U1), UU1I);
400 gmm::copy(gmm::real_part(U2), UU2R); gmm::copy(gmm::imag_part(U2), UU2I);
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
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,
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
457 ga_workspace workspace;
458 model_real_plain_vector UUR(mf.
nb_dof()), UUI(mf.
nb_dof());
459 gmm::copy(gmm::real_part(U), UUR);
460 gmm::copy(gmm::imag_part(U), UUI);
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
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
483 ga_workspace workspace;
484 model_real_plain_vector UU1(mf1.
nb_dof()), UU2(mf2.
nb_dof());
485 gmm::copy(U1, UU1); gmm::copy(U2, UU2);
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,
498 ga_workspace workspace;
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
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());
514 gmm::copy(gmm::real_part(U1), UU1R); gmm::copy(gmm::imag_part(U1), UU1I);
515 gmm::copy(gmm::real_part(U2), UU2R); gmm::copy(gmm::imag_part(U2), UU2I);
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
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_
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,
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_
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
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_
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_
660 const mesh_fem *mf_data,
const model_real_plain_vector &A,
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_
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,
748 ga_workspace workspace;
749 gmm::sub_interval Iu1(0, mf1.
nb_dof()), Iu2(0, 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,
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());
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");
832 template<
typename VECT1,
typename VECT2>
834 const mesh_fem &mf_data,
const VECT2 &F,
836 GMM_ASSERT1(mf_data.
get_qdim() == 1 ||
838 "invalid data mesh fem (same Qdim or Qdim=1 required)");
839 asm_real_or_complex_1_param_vec
840 (const_cast<VECT1 &>(B), mim, mf, &mf_data, F, rg,
"A:Test_u");
848 template<
typename VECT1,
typename VECT2>
852 asm_real_or_complex_1_param_vec
853 (const_cast<VECT1 &>(B), mim, mf, 0, F, rg,
"A:Test_u");
860 template<
typename VECT1,
typename VECT2>
863 const mesh_fem &mf_data,
const VECT2 &F,
865 asm_real_or_complex_1_param_vec(B, mim, mf, &mf_data, F, rg,
866 "(Reshape(A, qdim(u), meshdim).Normal):Test_u");
873 template<
typename VECT1,
typename VECT2>
877 { asm_real_or_complex_1_param_vec(B, mim, mf, 0,F,rg,
878 "(Reshape(A, qdim(u), meshdim).Normal):Test_u"); }
899 template<
typename MAT,
typename VECT>
901 const mesh_fem &mf_d,
const VECT &Q,
904 asm_real_or_complex_1_param_mat
905 (M, mim,mf_u,&mf_d,Q,rg,
"(Reshape(A,qdim(u),qdim(u)).Test_u):Test2_u");
907 asm_real_or_complex_1_param_mat
908 (M, mim, mf_u, &mf_d, Q, rg,
"(A*Test_u):Test2_u");
909 else GMM_ASSERT1(
false,
"invalid data mesh fem");
912 template<
typename MAT,
typename VECT>
913 void asm_homogeneous_qu_term(MAT &M,
const mesh_im &mim,
914 const mesh_fem &mf_u,
const VECT &Q,
916 if (gmm::vect_size(Q) == 1)
917 asm_real_or_complex_1_param_mat
918 (M, mim,mf_u,0,Q,rg,
"(A*Test_u):Test2_u");
920 asm_real_or_complex_1_param_mat
921 (M, mim,mf_u,0,Q,rg,
"(Reshape(A,qdim(u),qdim(u)).Test_u):Test2_u");
928 template<
class MAT,
class VECT>
931 const mesh_fem &mf_data,
const VECT &LAMBDA,
const VECT &MU,
933 ga_workspace workspace;
934 gmm::sub_interval Iu(0, mf.
nb_dof());
935 base_vector u(mf.
nb_dof()), lambda(gmm::vect_size(LAMBDA));
936 base_vector mu(gmm::vect_size(MU));
937 gmm::copy(LAMBDA, lambda); gmm::copy(MU, mu);
938 workspace.add_fem_variable(
"u", mf, Iu, u);
939 workspace.add_fem_constant(
"lambda", mf_data, lambda);
940 workspace.add_fem_constant(
"mu", mf_data, mu);
941 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)" 942 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
943 workspace.assembly(2);
944 if (gmm::mat_nrows(workspace.assembled_matrix()))
945 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
950 const mesh_fem &mf_data,
const model_real_plain_vector &LAMBDA,
951 const model_real_plain_vector &MU,
953 ga_workspace workspace;
954 gmm::sub_interval Iu(0, mf.
nb_dof());
955 base_vector u(mf.
nb_dof());
956 workspace.add_fem_variable(
"u", mf, Iu, u);
957 workspace.add_fem_constant(
"lambda", mf_data, LAMBDA);
958 workspace.add_fem_constant(
"mu", mf_data, MU);
959 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)" 960 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
961 workspace.set_assembled_matrix(M);
962 workspace.assembly(2);
970 template<
class MAT,
class VECT>
973 const VECT &LAMBDA,
const VECT &MU,
975 ga_workspace workspace;
976 gmm::sub_interval Iu(0, mf.
nb_dof());
977 base_vector u(mf.
nb_dof()), lambda(gmm::vect_size(LAMBDA));
978 base_vector mu(gmm::vect_size(MU));
979 gmm::copy(LAMBDA, lambda); gmm::copy(MU, mu);
980 workspace.add_fem_variable(
"u", mf, Iu, u);
981 workspace.add_fixed_size_constant(
"lambda", lambda);
982 workspace.add_fixed_size_constant(
"mu", mu);
983 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)" 984 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
985 workspace.assembly(2);
986 if (gmm::mat_nrows(workspace.assembled_matrix()))
987 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
993 const model_real_plain_vector &LAMBDA,
const model_real_plain_vector &MU,
995 ga_workspace workspace;
996 gmm::sub_interval Iu(0, mf.
nb_dof());
997 base_vector u(mf.
nb_dof());
998 workspace.add_fem_variable(
"u", mf, Iu, u);
999 workspace.add_fixed_size_constant(
"lambda", LAMBDA);
1000 workspace.add_fixed_size_constant(
"mu", MU);
1001 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)" 1002 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
1003 workspace.set_assembled_matrix(M);
1004 workspace.assembly(2);
1017 template<
typename MAT,
typename VECT>
void 1029 template<
typename MAT>
1033 ga_workspace workspace;
1034 gmm::sub_interval Iu(0, mf_u.
nb_dof()), Ip(Iu.last(), mf_p.
nb_dof());
1036 workspace.add_fem_variable(
"u", mf_u, Iu, u);
1037 workspace.add_fem_variable(
"p", mf_p, Ip, p);
1038 workspace.add_expression(
"Test_p*Div_Test2_u", mim, rg);
1039 workspace.assembly(2);
1040 if (gmm::mat_nrows(workspace.assembled_matrix()))
1041 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(), Ip, Iu),
1042 const_cast<MAT &>(B));
1048 ga_workspace workspace;
1049 gmm::sub_interval Iu(0, mf_u.
nb_dof()), Ip(0, mf_p.
nb_dof());
1051 workspace.add_fem_variable(
"u", mf_u, Iu, u);
1052 workspace.add_fem_variable(
"p", mf_p, Ip, p);
1053 workspace.add_expression(
"Test_p*Div_Test2_u", mim, rg);
1054 workspace.set_assembled_matrix(B);
1055 workspace.assembly(2);
1064 template<
typename MAT>
1068 ga_workspace workspace;
1069 gmm::sub_interval Iu(0, mf.
nb_dof());
1070 base_vector u(mf.
nb_dof());
1071 workspace.add_fem_variable(
"u", mf, Iu, u);
1072 workspace.add_expression(
"Grad_Test_u:Grad_Test2_u", mim, rg);
1073 workspace.assembly(2);
1074 if (gmm::mat_nrows(workspace.assembled_matrix()))
1075 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
1081 ga_workspace workspace;
1082 gmm::sub_interval Iu(0, mf.
nb_dof());
1083 base_vector u(mf.
nb_dof());
1084 workspace.add_fem_variable(
"u", mf, Iu, u);
1085 workspace.add_expression(
"Grad_Test_u:Grad_Test2_u", mim, rg);
1086 workspace.set_assembled_matrix(M);
1087 workspace.assembly(2);
1094 template<
typename MAT>
1106 template<
typename MAT,
typename VECT>
1110 GMM_ASSERT1(mf_data.
get_qdim() == 1
1111 && gmm::vect_size(A) == mf_data.
nb_dof(),
"invalid data");
1112 asm_real_or_complex_1_param_mat
1113 (M, mim, mf, &mf_data, A, rg,
"(A*Grad_Test_u):Grad_Test2_u");
1119 template<
typename MAT,
typename VECT>
1149 template<
typename MAT,
typename VECT>
1153 asm_real_or_complex_1_param_mat
1154 (M, mim, mf, &mf_data, A, rg,
1155 "(Reshape(A,meshdim,meshdim)*Grad_Test_u):Grad_Test2_u");
1160 template<
typename MAT,
typename VECT>
1164 asm_real_or_complex_1_param_mat
1165 (M, mim, mf, 0, A, rg,
1166 "(Reshape(A,meshdim,meshdim)*Grad_Test_u):Grad_Test2_u");
1171 template<
typename MAT,
typename VECT>
1174 const mesh_fem &mf_data,
const VECT &A,
1176 asm_real_or_complex_1_param_mat
1177 (M, mim, mf, &mf_data, A, rg,
1178 "(Grad_Test_u*(Reshape(A,meshdim,meshdim)')):Grad_Test2_u");
1183 template<
typename MAT,
typename VECT>
1187 asm_real_or_complex_1_param_mat
1188 (M, mim, mf, 0, A, rg,
1189 "(Grad_Test_u*(Reshape(A,meshdim,meshdim)')):Grad_Test2_u");
1197 template<
typename MAT,
typename VECT>
void 1202 asm_real_or_complex_1_param_mat
1203 (M, mim, mf, &mf_data, A, rg,
1204 "(Reshape(A,qdim(u),meshdim,qdim(u),meshdim):Grad_Test_u):Grad_Test2_u");
1211 template<
typename MAT,
typename VECT>
void 1216 asm_real_or_complex_1_param_mat
1217 (M, mim, mf, 0, A, rg,
1218 "(Reshape(A,qdim(u),meshdim,qdim(u),meshdim):Grad_Test_u):Grad_Test2_u");
1229 template<
typename MAT,
typename VECT>
1231 const mesh_fem &mf_data,
const VECT &K_squared,
1233 typedef typename gmm::linalg_traits<MAT>::value_type T;
1234 asm_Helmholtz_(M, mim, mf_u, &mf_data, K_squared, rg, T());
1237 template<
typename MAT,
typename VECT,
typename T>
1239 const mesh_fem *mf_data,
const VECT &K_squared,
1241 asm_real_or_complex_1_param_mat
1242 (M, mim, mf_u, mf_data, K_squared, rg,
1243 "(A*Test_u).Test2_u - Grad_Test_u:Grad_Test2_u");
1246 template<
typename MAT,
typename VECT,
typename T>
1248 const mesh_fem *mf_data,
const VECT &K_squared,
1258 ga_workspace workspace;
1259 gmm::sub_interval Iur(0, mf_u.
nb_dof()), Iui(Iur.last(), mf_u.
nb_dof());
1260 base_vector u(mf_u.
nb_dof());
1261 base_vector AR(gmm::vect_size(K_squared)), AI(gmm::vect_size(K_squared));
1262 gmm::copy(gmm::real_part(K_squared), AR);
1263 gmm::copy(gmm::imag_part(K_squared), AI);
1264 workspace.add_fem_variable(
"u", mf_u, Iur, u);
1265 workspace.add_fem_variable(
"ui", mf_u, Iui, u);
1268 workspace.add_fem_constant(
"A", *mf_data, AR);
1269 workspace.add_fem_constant(
"AI", *mf_data, AI);
1271 workspace.add_fixed_size_constant(
"A", AR);
1272 workspace.add_fixed_size_constant(
"AI", AI);
1274 workspace.add_expression(
"(A*Test_u).Test2_u - Grad_Test_u:Grad_Test2_u",
1276 workspace.add_expression(
"(AI*Test_ui).Test2_ui", mim, rg);
1277 workspace.assembly(2);
1279 if (gmm::mat_nrows(workspace.assembled_matrix()))
1280 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(),Iur,Iur),
1281 const_cast<MAT &>(M));
1282 if (gmm::mat_nrows(workspace.assembled_matrix()) > mf_u.
nb_dof())
1283 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(),Iui,Iui),
1284 gmm::imag_part(const_cast<MAT &>(M)));
1298 template<
typename MAT,
typename VECT>
1302 typedef typename gmm::linalg_traits<MAT>::value_type T;
1303 asm_Helmholtz_(M, mim, mf_u, 0, K_squared, rg, T());
1306 enum { ASMDIR_BUILDH = 1, ASMDIR_BUILDR = 2, ASMDIR_SIMPLIFY = 4,
1307 ASMDIR_BUILDALL = 7 };
1327 template<
typename MAT,
typename VECT1,
typename VECT2>
1332 int version = ASMDIR_BUILDALL) {
1333 typedef typename gmm::linalg_traits<VECT1>::value_type value_type;
1334 typedef typename gmm::number_traits<value_type>::magnitude_type magn_type;
1336 if ((version & ASMDIR_SIMPLIFY) &&
1338 GMM_WARNING1(
"Sorry, no simplification for reduced fems");
1339 version = (version & (ASMDIR_BUILDR | ASMDIR_BUILDH));
1344 "invalid data mesh fem (Qdim=1 required)");
1345 if (version & ASMDIR_BUILDH) {
1347 gmm::clean(H, gmm::default_tol(magn_type())
1348 * gmm::mat_maxnorm(H) * magn_type(1000));
1350 if (version & ASMDIR_BUILDR)
1355 pfem pf_u, pf_r, pf_m;
1356 bool warning_msg1 =
false, warning_msg2 =
false;
1357 dal::bit_vector simplifiable_dofs, nonsimplifiable_dofs;
1358 std::vector<size_type> simplifiable_indices(mf_mult.
nb_basic_dof());
1359 std::vector<value_type> simplifiable_values(mf_mult.
nb_basic_dof());
1360 std::vector<value_type> v1, v2, v3;
1362 for (
mr_visitor v(region); !v.finished(); v.next()) {
1363 GMM_ASSERT1(v.is_face(),
"attempt to impose a dirichlet " 1364 "on the interior of the domain!");
1370 "attempt to impose a dirichlet " 1371 "condition on a convex with no FEM!");
1376 if (!pf_m->is_lagrange() && !warning_msg1) {
1377 GMM_WARNING3(
"Dirichlet condition with non-lagrange multiplier fem. " 1378 "see the documentation about Dirichlet conditions.");
1379 warning_msg1 =
true;
1382 if (!(version & ASMDIR_SIMPLIFY))
continue;
1384 mesh_fem::ind_dof_face_ct pf_u_ct
1386 mesh_fem::ind_dof_face_ct pf_r_ct
1388 mesh_fem::ind_dof_face_ct pf_m_ct
1393 size_type pf_u_nbdf_loc = pf_u->structure(cv)->nb_points_of_face(f);
1394 size_type pf_m_nbdf_loc = pf_m->structure(cv)->nb_points_of_face(f);
1397 if (pf_u_nbdf < pf_m_nbdf && !warning_msg2) {
1398 GMM_WARNING2(
"Dirichlet condition with a too rich multiplier fem. " 1399 "see the documentation about Dirichlet conditions.");
1400 warning_msg2 =
true;
1403 if (pf_u != pf_r || pf_u_nbdf != pf_m_nbdf ||
1404 ((pf_u != pf_r) && (pf_u_nbdf_loc != pf_m_nbdf_loc))) {
1405 for (
size_type i = 0; i < pf_m_nbdf; ++i)
1406 nonsimplifiable_dofs.add(pf_m_ct[i]);
1410 for (
size_type i = 0; i < pf_m_nbdf; ++i) {
1411 simplifiable_dofs.add(pf_m_ct[i]);
1412 simplifiable_indices[pf_m_ct[i]] = pf_u_ct[i];
1415 if (!(version & ASMDIR_BUILDR))
continue;
1419 for (
size_type i = 0; i < pf_m_nbdf; ++i) {
1420 simplifiable_values[pf_m_ct[i]]
1421 = r_data[pf_r_ct[i/Qratio]*Qratio+(i%Qratio)];
1426 if (version & ASMDIR_SIMPLIFY) {
1427 if (simplifiable_dofs.card() > 0)
1428 { GMM_TRACE3(
"Simplification of the Dirichlet condition"); }
1430 GMM_TRACE3(
"Sorry, no simplification of the Dirichlet condition");
1431 if (nonsimplifiable_dofs.card() > 0 && simplifiable_dofs.card() > 0)
1432 GMM_WARNING3(
"Partial simplification of the Dirichlet condition");
1434 for (dal::bv_visitor i(simplifiable_dofs); !i.finished(); ++i)
1435 if (!(nonsimplifiable_dofs[i])) {
1436 if (version & ASMDIR_BUILDH) {
1438 for (
size_type j = 0; j < cv_ct.size(); ++j) {
1443 H(i, simplifiable_indices[i]) = value_type(1);
1445 if (version & ASMDIR_BUILDR) R[i] = simplifiable_values[i];
1450 template<
typename MATRM,
typename VECT1,
typename VECT2>
1451 void assembling_Dirichlet_condition
1456 GMM_ASSERT1(!(mf.
is_reduced()),
"This function is not adapted to " 1457 "reduced finite element methods");
1460 for (dal::bv_visitor cv(mf.
convex_index()); !cv.finished(); ++cv) {
1466 if (nndof.is_in(dof1) && pf1->dof_types()[i] == ldof) {
1472 if (!(nndof.is_in(dof2)) &&
1475 B[dof2+k] -= RM(dof2+k, dof1+l) * F[dof1+l];
1476 RM(dof2+k, dof1+l) = RM(dof1+l, dof2+k) = 0;
1480 { RM(dof1+k, dof1+k) = 1; B[dof1+k] = F[dof1+k]; }
1504 template<
typename MAT,
typename VECT1,
typename VECT2,
typename VECT3>
1509 int version = ASMDIR_BUILDALL) {
1512 if ((version & ASMDIR_SIMPLIFY) &&
1514 GMM_WARNING1(
"Sorry, no simplification for reduced fems");
1515 version = (version & ASMDIR_BUILDR);
1520 "invalid data mesh fem (Qdim=1 required)");
1521 if (version & ASMDIR_BUILDH) {
1523 std::vector<size_type> ind(0);
1527 if (!(bdof[i])) ind.push_back(i);
1528 gmm::clear(gmm::sub_matrix(H, gmm::sub_index(ind)));
1530 if (version & ASMDIR_BUILDR)
1532 if (!(version & ASMDIR_SIMPLIFY))
return;
1535 if (&mf_r == &mf_h) {
1536 for (
mr_visitor v(region); !v.finished(); v.next()) {
1542 "attempt to impose a dirichlet " 1543 "condition on a convex with no FEM!");
1553 for (
size_type i = 0; i < cvs_u->nb_points_of_face(f); ++i) {
1557 size_type ind_u = cvs_u->ind_points_of_face(f)[i];
1560 for (
size_type j = 0; j < cvs_rh->nb_points_of_face(f); ++j) {
1561 size_type ind_rh = cvs_rh->ind_points_of_face(f)[j];
1573 if (tdof_u == tdof_rh &&
1574 gmm::vect_dist2_sqr((*(pf_u->node_tab(cv)))[ind_u],
1575 (*(pf_rh->node_tab(cv)))[ind_rh])
1582 if (version & ASMDIR_BUILDH)
1588 if (version & ASMDIR_BUILDH)
1589 for (
unsigned jj=0; jj < Q; jj++) {
1592 H(dof_u, dof_u2) = h_data[(jj*Q+q) + Q*Q*(dof_rh)];
1594 if (version & ASMDIR_BUILDR) R[dof_u] = r_data[dof_rh*Q+q];
1611 template<
typename MAT1,
typename MAT2,
typename VECT1,
typename VECT2>
1613 const VECT1 &R, VECT2 &U0) {
1615 typedef typename gmm::linalg_traits<MAT1>::value_type T;
1616 typedef typename gmm::number_traits<T>::magnitude_type MAGT;
1617 typedef typename gmm::temporary_vector<MAT1>::vector_type TEMP_VECT;
1618 MAGT tol = gmm::default_tol(MAGT());
1619 MAGT norminfH = gmm::mat_maxnorm(H);
1620 size_type nbd = gmm::mat_ncols(H), nbase = 0, nbr = gmm::mat_nrows(H);
1621 TEMP_VECT aux(nbr), e(nbd), f(nbd);
1627 if (!(gmm::is_col_matrix(H)))
1628 GMM_WARNING2(
"Dirichlet_nullspace inefficient for a row matrix H");
1633 gmm::clear(e); e[i] = T(1);
1634 gmm::mult(H, e, aux);
1635 MAGT n = gmm::vect_norm2(aux);
1637 if (n < norminfH*tol*1000) {
1638 NS(i, nbase++) = T(1); nn[i] =
true;
1643 if (gmm::abs(gmm::vect_sp(aux, base_img[j])) > MAGT(0))
1644 { good =
false;
break; }
1647 gmm::scale(f, T(MAGT(1)/n)); gmm::scale(aux, T(MAGT(1)/n));
1648 base_img_inv[nb_bimg] = TEMP_VECT(nbd);
1649 gmm::copy(f, base_img_inv[nb_bimg]);
1650 gmm::clean(aux, gmm::vect_norminf(aux)*tol);
1651 base_img[nb_bimg] = TEMP_VECT(nbr);
1652 gmm::copy(aux, base_img[nb_bimg++]);
1661 gmm::clear(e); e[i] = T(1); gmm::clear(f); f[i] = T(1);
1662 gmm::mult(H, e, aux);
1663 for (
size_type j = 0; j < nb_bimg; ++j) {
1664 T c = gmm::vect_sp(aux, base_img[j]);
1667 gmm::add(gmm::scaled(base_img[j], -c), aux);
1668 gmm::add(gmm::scaled(base_img_inv[j], -c), f);
1671 if (gmm::vect_norm2(aux) < norminfH*tol*MAGT(10000)) {
1672 gmm::copy(f, gmm::mat_col(NS, nbase++));
1675 MAGT n = gmm::vect_norm2(aux);
1676 gmm::scale(f, T(MAGT(1)/n)); gmm::scale(aux, T(MAGT(1)/n));
1677 gmm::clean(f, tol*gmm::vect_norminf(f));
1678 gmm::clean(aux, tol*gmm::vect_norminf(aux));
1679 base_img_inv[nb_bimg] = TEMP_VECT(nbd);
1680 gmm::copy(f, base_img_inv[nb_bimg]);
1681 base_img[nb_bimg] = TEMP_VECT(nbr);
1682 gmm::copy(aux, base_img[nb_bimg++]);
1688 for (
size_type i = 0; i < nb_bimg; ++i) {
1689 T c = gmm::vect_sp(base_img[i], R);
1690 gmm::add(gmm::scaled(base_img_inv[i], c), U0);
1693 for (
size_type i = nb_triv_base; i < nbase; ++i) {
1694 for (
size_type j = nb_triv_base; j < i; ++j) {
1695 T c = gmm::vect_sp(gmm::mat_col(NS,i), gmm::mat_col(NS,j));
1697 gmm::add(gmm::scaled(gmm::mat_col(NS,j), -c), gmm::mat_col(NS,i));
1699 gmm::scale(gmm::mat_col(NS,i),
1700 T(1) / gmm::vect_norm2(gmm::mat_col(NS,i)));
1703 for (
size_type j = nb_triv_base; j < nbase; ++j) {
1704 T c = gmm::vect_sp(gmm::mat_col(NS,j), U0);
1706 gmm::add(gmm::scaled(gmm::mat_col(NS,j), -c), U0);
1709 gmm::mult(H, U0, gmm::scaled(R, T(-1)), aux);
1710 if (gmm::vect_norm2(aux) > gmm::vect_norm2(U0)*tol*MAGT(10000))
1711 GMM_WARNING2(
"Dirichlet condition not well inverted: residu=" 1712 << gmm::vect_norm2(aux));
virtual size_type nb_basic_dof_of_element(size_type cv) const
Return the number of degrees of freedom attached to a given convex.
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
structure used to hold a set of convexes and/or convex faces.
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.
dof_description * pdof_description
Type representing a pointer on a dof_description.
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_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.
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 .
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.
static mesh_region all_convexes()
provide a default value for the mesh_region parameters of assembly procedures etc.
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.
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_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_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) ...
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_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.
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! us...
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).
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
Describe an integration method linked to a mesh.
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_laplacian(const MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_region &rg=mesh_region::all_convexes())
assembly of .
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 , where is in the space of multipliers correspondi...
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...
virtual const mesh::ind_cv_ct & convex_to_basic_dof(size_type d) const
Return the list of convexes attached to the specified dof.
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.
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...
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.
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
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).
size_t size_type
used as the common size type in the library
bool dof_compatibility(pdof_description, pdof_description)
Says if the two dofs can be identified.
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.
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.
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...
virtual dim_type get_qdim() const
Return the Q dimension.
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).
"iterator" class for regions.
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 ...
A langage for generic assembly of pde boundary value problems.
bool is_reduced() const
Return true if a reduction matrix is applied to the dofs.
GEneric Tool for Finite Element Methods.
pdof_description lagrange_dof(dim_type d)
Description of a unique dof of lagrange type (value at the node).
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.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Describe a finite element method linked to a mesh.
gmm::uint16_type short_type
used as the common short type integer in the library
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_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).
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_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...
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...
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
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...
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.
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
const mesh & linked_mesh() const
Give a reference to the linked mesh of type mesh.
Generic assembly implementation.
const dal::bit_vector & convex_index() const
Get the set of convexes where a finite element has been assigned.
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_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.
virtual ind_dof_ct ind_basic_dof_of_element(size_type cv) const
Give an array of the dof numbers a of convex.
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_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
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