41 #ifndef GETFEM_ASSEMBLING_H__
42 #define GETFEM_ASSEMBLING_H__
53 template<
typename VEC>
57 {
return sqrt(asm_L2_norm_sqr(mim, mf, U, rg)); }
59 template<
typename VEC>
60 scalar_type asm_L2_norm_sqr
61 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
63 return asm_L2_norm_sqr(mim, mf, U, rg,
64 typename gmm::linalg_traits<VEC>::value_type());
67 template<
typename VEC,
typename T>
68 inline scalar_type asm_L2_norm_sqr(
const mesh_im &mim,
const mesh_fem &mf,
69 const VEC &U,
const mesh_region &rg_, T) {
70 ga_workspace workspace;
71 model_real_plain_vector UU(mf.nb_dof());
73 gmm::sub_interval Iu(0, mf.nb_dof());
74 workspace.add_fem_variable(
"u", mf, Iu, UU);
75 workspace.add_expression(
"u.u", mim, rg_);
76 workspace.assembly(0);
77 return workspace.assembled_potential();
80 inline scalar_type asm_L2_norm_sqr(
const mesh_im &mim,
const mesh_fem &mf,
81 const model_real_plain_vector &U,
82 const mesh_region &rg_, scalar_type) {
83 ga_workspace workspace;
84 gmm::sub_interval Iu(0, mf.nb_dof());
85 workspace.add_fem_variable(
"u", mf, Iu, U);
86 workspace.add_expression(
"u.u", mim, rg_);
87 workspace.assembly(0);
88 return workspace.assembled_potential();
91 template<
typename VEC,
typename T>
92 inline scalar_type asm_L2_norm_sqr(
const mesh_im &mim,
const mesh_fem &mf,
94 const mesh_region &rg, std::complex<T>) {
95 ga_workspace workspace;
96 model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
99 gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
100 workspace.add_fem_variable(
"u", mf, Iur, UUR);
101 workspace.add_fem_variable(
"v", mf, Iui, UUI);
102 workspace.add_expression(
"u.u + v.v", mim, rg);
103 workspace.assembly(0);
104 return workspace.assembled_potential();
113 template<
typename VEC1,
typename VEC2>
116 const mesh_fem &mf2,
const VEC2 &U2,
118 return sqrt(asm_L2_dist_sqr(mim, mf1, U1, mf2, U2, rg,
119 typename gmm::linalg_traits<VEC1>::value_type()));
122 template<
typename VEC1,
typename VEC2,
typename T>
123 inline scalar_type asm_L2_dist_sqr
124 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
125 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, T) {
126 ga_workspace workspace;
127 model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
128 gmm::copy(U1, UU1); gmm::copy(U2, UU2);
129 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
130 workspace.add_fem_variable(
"u1", mf1, Iu1, UU1);
131 workspace.add_fem_variable(
"u2", mf2, Iu2, UU2);
132 workspace.add_expression(
"(u2-u1).(u2-u1)", mim, rg);
133 workspace.assembly(0);
134 return workspace.assembled_potential();
137 inline scalar_type asm_L2_dist_sqr
138 (
const mesh_im &mim,
const mesh_fem &mf1,
const model_real_plain_vector &U1,
139 const mesh_fem &mf2,
const model_real_plain_vector &U2,
140 mesh_region rg, scalar_type) {
141 ga_workspace workspace;
142 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
143 workspace.add_fem_variable(
"u1", mf1, Iu1, U1);
144 workspace.add_fem_variable(
"u2", mf2, Iu2, U2);
145 workspace.add_expression(
"(u2-u1).(u2-u1)", mim, rg);
146 workspace.assembly(0);
147 return workspace.assembled_potential();
150 template<
typename VEC1,
typename VEC2,
typename T>
151 inline scalar_type asm_L2_dist_sqr
152 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
153 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, std::complex<T>) {
154 ga_workspace workspace;
155 model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
156 model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
159 gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
160 gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
161 gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
162 workspace.add_fem_variable(
"u1", mf1, Iu1r, UU1R);
163 workspace.add_fem_variable(
"u2", mf2, Iu2r, UU2R);
164 workspace.add_fem_variable(
"v1", mf1, Iu1i, UU1I);
165 workspace.add_fem_variable(
"v2", mf2, Iu2i, UU2I);
166 workspace.add_expression(
"(u2-u1).(u2-u1) + (v2-v1).(v2-v1)", mim, rg);
167 workspace.assembly(0);
168 return workspace.assembled_potential();
176 template<
typename VEC>
180 typedef typename gmm::linalg_traits<VEC>::value_type T;
181 return sqrt(asm_H1_semi_norm_sqr(mim, mf, U, rg, T()));
184 template<
typename VEC,
typename T>
185 inline scalar_type asm_H1_semi_norm_sqr
186 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
187 const mesh_region &rg_, T) {
188 ga_workspace workspace;
189 model_real_plain_vector UU(mf.nb_dof()); gmm::copy(U, UU);
190 gmm::sub_interval Iu(0, mf.nb_dof());
191 workspace.add_fem_variable(
"u", mf, Iu, UU);
192 workspace.add_expression(
"Grad_u:Grad_u", mim, rg_);
193 workspace.assembly(0);
194 return workspace.assembled_potential();
197 inline scalar_type asm_H1_semi_norm_sqr
198 (
const mesh_im &mim,
const mesh_fem &mf,
const model_real_plain_vector &U,
199 const mesh_region &rg_, scalar_type) {
200 ga_workspace workspace;
201 gmm::sub_interval Iu(0, mf.nb_dof());
202 workspace.add_fem_variable(
"u", mf, Iu, U);
203 workspace.add_expression(
"Grad_u:Grad_u", mim, rg_);
204 workspace.assembly(0);
205 return workspace.assembled_potential();
209 template<
typename VEC,
typename T>
210 inline scalar_type asm_H1_semi_norm_sqr
211 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
212 const mesh_region &rg, std::complex<T>) {
213 ga_workspace workspace;
214 model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
217 gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
218 workspace.add_fem_variable(
"u", mf, Iur, UUR);
219 workspace.add_fem_variable(
"v", mf, Iui, UUI);
220 workspace.add_expression(
"Grad_u:Grad_u + Grad_v:Grad_v", mim, rg);
221 workspace.assembly(0);
222 return workspace.assembled_potential();
231 template<
typename VEC1,
typename VEC2>
234 const mesh_fem &mf2,
const VEC2 &U2,
236 return sqrt(asm_H1_semi_dist_sqr(mim, mf1, U1, mf2, U2, rg,
237 typename gmm::linalg_traits<VEC1>::value_type()));
240 template<
typename VEC1,
typename VEC2,
typename T>
241 inline scalar_type asm_H1_semi_dist_sqr
242 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
243 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, T) {
244 ga_workspace workspace;
245 model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
246 gmm::copy(U1, UU1); gmm::copy(U2, UU2);
247 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
248 workspace.add_fem_variable(
"u1", mf1, Iu1, UU1);
249 workspace.add_fem_variable(
"u2", mf2, Iu2, UU2);
250 workspace.add_expression(
"(Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
251 workspace.assembly(0);
252 return workspace.assembled_potential();
255 inline scalar_type asm_H1_semi_dist_sqr
256 (
const mesh_im &mim,
const mesh_fem &mf1,
const model_real_plain_vector &U1,
257 const mesh_fem &mf2,
const model_real_plain_vector &U2,
258 mesh_region rg, scalar_type) {
259 ga_workspace workspace;
260 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
261 workspace.add_fem_variable(
"u1", mf1, Iu1, U1);
262 workspace.add_fem_variable(
"u2", mf2, Iu2, U2);
263 workspace.add_expression(
"(Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
264 workspace.assembly(0);
265 return workspace.assembled_potential();
268 template<
typename VEC1,
typename VEC2,
typename T>
269 inline scalar_type asm_H1_semi_dist_sqr
270 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
271 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, std::complex<T>) {
272 ga_workspace workspace;
273 model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
274 model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
277 gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
278 gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
279 gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
280 workspace.add_fem_variable(
"u1", mf1, Iu1r, UU1R);
281 workspace.add_fem_variable(
"u2", mf2, Iu2r, UU2R);
282 workspace.add_fem_variable(
"v1", mf1, Iu1i, UU1I);
283 workspace.add_fem_variable(
"v2", mf2, Iu2i, UU2I);
284 workspace.add_expression(
"(Grad_u2-Grad_u1):(Grad_u2-Grad_u1)"
285 "+ (Grad_v2-Grad_v1):(Grad_v2-Grad_v1)", mim, rg);
286 workspace.assembly(0);
287 return workspace.assembled_potential();
299 template<
typename VEC>
303 typedef typename gmm::linalg_traits<VEC>::value_type T;
304 return sqrt(asm_H1_norm_sqr(mim, mf, U, rg, T()));
307 template<
typename VEC,
typename T>
308 inline scalar_type asm_H1_norm_sqr
309 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
310 const mesh_region &rg_, T) {
311 ga_workspace workspace;
312 model_real_plain_vector UU(mf.nb_dof()); gmm::copy(U, UU);
313 gmm::sub_interval Iu(0, mf.nb_dof());
314 workspace.add_fem_variable(
"u", mf, Iu, UU);
315 workspace.add_expression(
"u.u + Grad_u:Grad_u", mim, rg_);
316 workspace.assembly(0);
317 return workspace.assembled_potential();
320 inline scalar_type asm_H1_norm_sqr
321 (
const mesh_im &mim,
const mesh_fem &mf,
const model_real_plain_vector &U,
322 const mesh_region &rg_, scalar_type) {
323 ga_workspace workspace;
324 gmm::sub_interval Iu(0, mf.nb_dof());
325 workspace.add_fem_variable(
"u", mf, Iu, U);
326 workspace.add_expression(
"u.u + Grad_u:Grad_u", mim, rg_);
327 workspace.assembly(0);
328 return workspace.assembled_potential();
332 template<
typename VEC,
typename T>
333 inline scalar_type asm_H1_norm_sqr
334 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
335 const mesh_region &rg, std::complex<T>) {
336 ga_workspace workspace;
337 model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
340 gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
341 workspace.add_fem_variable(
"u", mf, Iur, UUR);
342 workspace.add_fem_variable(
"v", mf, Iui, UUI);
343 workspace.add_expression(
"u.u+v.v + Grad_u:Grad_u+Grad_v:Grad_v", mim, rg);
344 workspace.assembly(0);
345 return workspace.assembled_potential();
352 template<
typename VEC1,
typename VEC2>
355 const mesh_fem &mf2,
const VEC2 &U2,
357 return sqrt(asm_H1_dist_sqr(mim, mf1, U1, mf2, U2, rg,
358 typename gmm::linalg_traits<VEC1>::value_type()));
361 template<
typename VEC1,
typename VEC2,
typename T>
362 inline scalar_type asm_H1_dist_sqr
363 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
364 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, T) {
365 ga_workspace workspace;
366 model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
367 gmm::copy(U1, UU1); gmm::copy(U2, UU2);
368 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
369 workspace.add_fem_variable(
"u1", mf1, Iu1, UU1);
370 workspace.add_fem_variable(
"u2", mf2, Iu2, UU2);
371 workspace.add_expression(
"(u2-u1).(u2-u1)"
372 "+ (Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
373 workspace.assembly(0);
374 return workspace.assembled_potential();
377 inline scalar_type asm_H1_dist_sqr
378 (
const mesh_im &mim,
const mesh_fem &mf1,
const model_real_plain_vector &U1,
379 const mesh_fem &mf2,
const model_real_plain_vector &U2,
380 mesh_region rg, scalar_type) {
381 ga_workspace workspace;
382 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
383 workspace.add_fem_variable(
"u1", mf1, Iu1, U1);
384 workspace.add_fem_variable(
"u2", mf2, Iu2, U2);
385 workspace.add_expression(
"(u2-u1).(u2-u1)"
386 "+ (Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
387 workspace.assembly(0);
388 return workspace.assembled_potential();
391 template<
typename VEC1,
typename VEC2,
typename T>
392 inline scalar_type asm_H1_dist_sqr
393 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
394 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, std::complex<T>) {
395 ga_workspace workspace;
396 model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
397 model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
400 gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
401 gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
402 gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
403 workspace.add_fem_variable(
"u1", mf1, Iu1r, UU1R);
404 workspace.add_fem_variable(
"u2", mf2, Iu2r, UU2R);
405 workspace.add_fem_variable(
"v1", mf1, Iu1i, UU1I);
406 workspace.add_fem_variable(
"v2", mf2, Iu2i, UU2I);
407 workspace.add_expression(
"(u2-u1).(u2-u1) + (v2-v1).(v2-v1)"
408 "+ (Grad_u2-Grad_u1):(Grad_u2-Grad_u1)"
409 "+ (Grad_v2-Grad_v1):(Grad_v2-Grad_v1)", mim, rg);
410 workspace.assembly(0);
411 return workspace.assembled_potential();
419 template<
typename VEC>
423 typedef typename gmm::linalg_traits<VEC>::value_type T;
424 return sqrt(asm_H2_semi_norm_sqr(mim, mf, U, rg, T()));
427 template<
typename VEC,
typename T>
428 inline scalar_type asm_H2_semi_norm_sqr
429 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
430 const mesh_region &rg_, T) {
431 ga_workspace workspace;
432 model_real_plain_vector UU(mf.nb_dof()); gmm::copy(U, UU);
433 gmm::sub_interval Iu(0, mf.nb_dof());
434 workspace.add_fem_variable(
"u", mf, Iu, UU);
435 workspace.add_expression(
"Hess_u:Hess_u", mim, rg_);
436 workspace.assembly(0);
437 return workspace.assembled_potential();
440 inline scalar_type asm_H2_semi_norm_sqr
441 (
const mesh_im &mim,
const mesh_fem &mf,
const model_real_plain_vector &U,
442 const mesh_region &rg_, scalar_type) {
443 ga_workspace workspace;
444 gmm::sub_interval Iu(0, mf.nb_dof());
445 workspace.add_fem_variable(
"u", mf, Iu, U);
446 workspace.add_expression(
"Hess_u:Hess_u", mim, rg_);
447 workspace.assembly(0);
448 return workspace.assembled_potential();
452 template<
typename VEC,
typename T>
453 inline scalar_type asm_H2_semi_norm_sqr
454 (
const mesh_im &mim,
const mesh_fem &mf,
const VEC &U,
455 const mesh_region &rg, std::complex<T>) {
456 ga_workspace workspace;
457 model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
460 gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
461 workspace.add_fem_variable(
"u", mf, Iur, UUR);
462 workspace.add_fem_variable(
"v", mf, Iui, UUI);
463 workspace.add_expression(
"Hess_u:Hess_u + Hess_v:Hess_v", mim, rg);
464 workspace.assembly(0);
465 return workspace.assembled_potential();
469 template<
typename VEC1,
typename VEC2>
470 inline scalar_type asm_H2_semi_dist
471 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
472 const mesh_fem &mf2,
const VEC2 &U2,
474 return sqrt(asm_H2_semi_dist_sqr(mim, mf1, U1, mf2, U2, rg,
475 typename gmm::linalg_traits<VEC1>::value_type()));
478 template<
typename VEC1,
typename VEC2,
typename T>
479 inline scalar_type asm_H2_semi_dist_sqr
480 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
481 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, T) {
482 ga_workspace workspace;
483 model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
485 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
486 workspace.add_fem_variable(
"u1", mf1, Iu1, UU1);
487 workspace.add_fem_variable(
"u2", mf2, Iu2, UU2);
488 workspace.add_expression(
"(Hess_u2-Hess_u1):(Hess_u2-Hess_u1)", mim, rg);
489 workspace.assembly(0);
490 return workspace.assembled_potential();
493 inline scalar_type asm_H2_semi_dist_sqr
494 (
const mesh_im &mim,
const mesh_fem &mf1,
const model_real_plain_vector &U1,
495 const mesh_fem &mf2,
const model_real_plain_vector &U2,
496 mesh_region rg, scalar_type) {
497 ga_workspace workspace;
498 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
499 workspace.add_fem_variable(
"u1", mf1, Iu1, U1);
500 workspace.add_fem_variable(
"u2", mf2, Iu2, U2);
501 workspace.add_expression(
"(Hess_u2-Hess_u1):(Hess_u2-Hess_u1)", mim, rg);
502 workspace.assembly(0);
503 return workspace.assembled_potential();
506 template<
typename VEC1,
typename VEC2,
typename T>
507 inline scalar_type asm_H2_semi_dist_sqr
508 (
const mesh_im &mim,
const mesh_fem &mf1,
const VEC1 &U1,
509 const mesh_fem &mf2,
const VEC2 &U2, mesh_region rg, std::complex<T>) {
510 ga_workspace workspace;
511 model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
512 model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
515 gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
516 gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
517 gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
518 workspace.add_fem_variable(
"u1", mf1, Iu1r, UU1R);
519 workspace.add_fem_variable(
"u2", mf2, Iu2r, UU2R);
520 workspace.add_fem_variable(
"v1", mf1, Iu1i, UU1I);
521 workspace.add_fem_variable(
"v2", mf2, Iu2i, UU2I);
522 workspace.add_expression(
"(Hess_u2-Hess_u1):(Hess_u2-Hess_u1)"
523 "+ (Hess_v2-Hess_v1):(Hess_v2-Hess_v1)", mim, rg);
524 workspace.assembly(0);
525 return workspace.assembled_potential();
532 template<
typename VEC>
537 typedef typename gmm::linalg_traits<VEC>::value_type T;
538 return sqrt(asm_H1_norm_sqr(mim, mf, U, rg, T())
539 + asm_H2_semi_norm_sqr(mim, mf, U, rg, T()));
546 template<
typename VEC1,
typename VEC2>
548 const mesh_fem &mf1,
const VEC1 &U1,
549 const mesh_fem &mf2,
const VEC2 &U2,
552 typedef typename gmm::linalg_traits<VEC1>::value_type T;
553 return sqrt(asm_H1_dist_sqr(mim,mf1,U1,mf2,U2,rg,T()) +
554 asm_H2_semi_dist_sqr(mim,mf1,U1,mf2,U2,rg,T()));
561 template <
typename MAT,
typename VECT>
562 inline void asm_real_or_complex_1_param_mat
563 (MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
const mesh_fem *mf_data,
564 const VECT &A,
const mesh_region &rg,
const char *assembly_description) {
565 asm_real_or_complex_1_param_mat_
566 (M, mim, mf_u, mf_data, A, rg, assembly_description,
567 typename gmm::linalg_traits<VECT>::value_type());
571 template<
typename MAT,
typename VECT,
typename T>
572 inline void asm_real_or_complex_1_param_mat_
573 (
const MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
574 const mesh_fem *mf_data,
const VECT &A,
const mesh_region &rg,
575 const char *assembly_description, T) {
576 ga_workspace workspace;
577 gmm::sub_interval Iu(0, mf_u.nb_dof());
578 base_vector u(mf_u.nb_dof()), AA(gmm::vect_size(A));
580 workspace.add_fem_variable(
"u", mf_u, Iu, u);
582 workspace.add_fem_constant(
"A", *mf_data, AA);
584 workspace.add_fixed_size_constant(
"A", AA);
585 workspace.add_expression(assembly_description, mim, rg);
586 workspace.assembly(2);
587 if (gmm::mat_nrows(workspace.assembled_matrix()))
588 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
591 inline void asm_real_or_complex_1_param_mat_
592 (model_real_sparse_matrix &M,
const mesh_im &mim,
const mesh_fem &mf_u,
593 const mesh_fem *mf_data,
const model_real_plain_vector &A,
594 const mesh_region &rg,
595 const char *assembly_description, scalar_type) {
596 ga_workspace workspace;
597 gmm::sub_interval Iu(0, mf_u.nb_dof());
598 base_vector u(mf_u.nb_dof());
599 workspace.add_fem_variable(
"u", mf_u, Iu, u);
601 workspace.add_fem_constant(
"A", *mf_data, A);
603 workspace.add_fixed_size_constant(
"A", A);
604 workspace.add_expression(assembly_description, mim, rg);
605 workspace.set_assembled_matrix(M);
606 workspace.assembly(2);
610 template<
typename MAT,
typename VECT,
typename T>
611 inline void asm_real_or_complex_1_param_mat_
612 (MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
const mesh_fem *mf_data,
613 const VECT &A,
const mesh_region &rg,
const char *assembly_description,
615 asm_real_or_complex_1_param_mat_(gmm::real_part(M),mim,mf_u,mf_data,
616 gmm::real_part(A),rg,
617 assembly_description, T());
618 asm_real_or_complex_1_param_mat_(gmm::imag_part(M),mim,mf_u,mf_data,
619 gmm::imag_part(A),rg,
620 assembly_description, T());
627 template <
typename MAT,
typename VECT>
628 inline void asm_real_or_complex_1_param_vec
629 (MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
const mesh_fem *mf_data,
630 const VECT &A,
const mesh_region &rg,
const char *assembly_description) {
631 asm_real_or_complex_1_param_vec_
632 (M, mim, mf_u, mf_data, A, rg, assembly_description,
633 typename gmm::linalg_traits<VECT>::value_type());
637 template<
typename VECTA,
typename VECT,
typename T>
638 inline void asm_real_or_complex_1_param_vec_
639 (
const VECTA &V,
const mesh_im &mim,
const mesh_fem &mf_u,
640 const mesh_fem *mf_data,
const VECT &A,
const mesh_region &rg,
641 const char *assembly_description, T) {
642 ga_workspace workspace;
643 gmm::sub_interval Iu(0, mf_u.nb_dof());
644 base_vector u(mf_u.nb_dof()), AA(gmm::vect_size(A));
646 workspace.add_fem_variable(
"u", mf_u, Iu, u);
648 workspace.add_fem_constant(
"A", *mf_data, AA);
650 workspace.add_fixed_size_constant(
"A", AA);
651 workspace.add_expression(assembly_description, mim, rg);
652 workspace.assembly(1);
653 if (gmm::vect_size(workspace.assembled_vector()))
654 gmm::add(workspace.assembled_vector(),
const_cast<VECTA &
>(V));
657 inline void asm_real_or_complex_1_param_vec_
658 (model_real_plain_vector &V,
const mesh_im &mim,
const mesh_fem &mf_u,
659 const mesh_fem *mf_data,
const model_real_plain_vector &A,
660 const mesh_region &rg,
661 const char *assembly_description, scalar_type) {
662 ga_workspace workspace;
663 gmm::sub_interval Iu(0, mf_u.nb_dof());
664 base_vector u(mf_u.nb_dof());
665 workspace.add_fem_variable(
"u", mf_u, Iu, u);
667 workspace.add_fem_constant(
"A", *mf_data, A);
669 workspace.add_fixed_size_constant(
"A", A);
670 workspace.add_expression(assembly_description, mim, rg);
671 workspace.set_assembled_vector(V);
672 workspace.assembly(1);
676 template<
typename MAT,
typename VECT,
typename T>
677 inline void asm_real_or_complex_1_param_vec_
678 (MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
const mesh_fem *mf_data,
679 const VECT &A,
const mesh_region &rg,
const char *assembly_description,
681 asm_real_or_complex_1_param_vec_(gmm::real_part(M),mim,mf_u,mf_data,
682 gmm::real_part(A),rg,
683 assembly_description, T());
684 asm_real_or_complex_1_param_vec_(gmm::imag_part(M),mim,mf_u,mf_data,
685 gmm::imag_part(A),rg,
686 assembly_description, T());
694 template<
typename MAT>
699 ga_workspace workspace;
700 gmm::sub_interval Iu1(0, mf1.
nb_dof());
701 base_vector u1(mf1.
nb_dof());
702 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
703 workspace.add_expression(
"Test_u1:Test2_u1", mim, rg);
704 workspace.assembly(2);
705 if (gmm::mat_nrows(workspace.assembled_matrix()))
706 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
710 (model_real_sparse_matrix &M,
const mesh_im &mim,
713 ga_workspace workspace;
714 gmm::sub_interval Iu1(0, mf1.nb_dof());
715 base_vector u1(mf1.nb_dof());
716 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
717 workspace.add_expression(
"Test_u1:Test2_u1", mim, rg);
718 workspace.set_assembled_matrix(M);
719 workspace.assembly(2);
727 template<
typename MAT>
731 ga_workspace workspace;
732 gmm::sub_interval Iu1(0, mf1.
nb_dof()), Iu2(Iu1.last(), mf2.
nb_dof());
734 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
735 workspace.add_fem_variable(
"u2", mf2, Iu2, u2);
736 workspace.add_expression(
"Test_u1:Test2_u2", mim, rg);
737 workspace.assembly(2);
738 if (gmm::mat_nrows(workspace.assembled_matrix()))
739 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(), Iu1, Iu2),
740 const_cast<MAT &
>(M));
744 (model_real_sparse_matrix &M,
const mesh_im &mim,
745 const mesh_fem &mf1,
const mesh_fem &mf2,
747 ga_workspace workspace;
748 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(0, mf2.nb_dof());
749 base_vector u1(mf1.nb_dof()), u2(mf2.nb_dof());
750 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
751 workspace.add_fem_variable(
"u2", mf2, Iu2, u2);
752 workspace.add_expression(
"Test_u1:Test2_u2", mim, rg);
753 workspace.set_assembled_matrix(M);
754 workspace.assembly(2);
762 template<
typename MAT,
typename VECT>
765 const mesh_fem &mf_data,
const VECT &A,
768 ga_workspace workspace;
769 gmm::sub_interval Iu1(0, mf1.
nb_dof()), Iu2(Iu1.last(), mf2.
nb_dof());
772 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
773 workspace.add_fem_variable(
"u2", mf2, Iu2, u2);
774 workspace.add_fem_constant(
"A", mf_data, AA);
775 workspace.add_expression(
"(A*Test_u1).Test2_u2", mim, rg);
776 workspace.assembly(2);
777 if (gmm::mat_nrows(workspace.assembled_matrix()))
778 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(), Iu1, Iu2),
779 const_cast<MAT &
>(M));
783 (model_real_sparse_matrix &M,
const mesh_im &mim,
784 const mesh_fem &mf1,
const mesh_fem &mf2,
785 const mesh_fem &mf_data,
const model_real_plain_vector &A,
788 ga_workspace workspace;
789 gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(0, mf2.nb_dof());
790 base_vector u1(mf1.nb_dof()), u2(mf2.nb_dof());
791 workspace.add_fem_variable(
"u1", mf1, Iu1, u1);
792 workspace.add_fem_variable(
"u2", mf2, Iu2, u2);
793 workspace.add_fem_constant(
"A", mf_data, A);
794 workspace.add_expression(
"(A*Test_u1).Test2_u2", mim, rg);
795 workspace.set_assembled_matrix(M);
796 workspace.assembly(2);
806 template<
typename MAT,
typename VECT>
810 asm_real_or_complex_1_param_mat
811 (M, mim, mf_u, &mf_data, F, rg,
"(A*Test_u):Test2_u");
819 template<
typename MAT,
typename VECT>
823 asm_real_or_complex_1_param_mat
824 (M, mim, mf_u, 0, F, rg,
"(A*Test_u):Test2_u");
830 template<
typename MAT>
833 size_type nbd = gmm::mat_ncols(M), nbr = gmm::mat_nrows(M);
834 GMM_ASSERT1(nbd == nbr,
"mass matrix is not square");
835 typedef typename gmm::linalg_traits<MAT>::value_type T;
836 std::vector<T> V(nbd), W(nbr);
839 gmm::clear(
const_cast<MAT &
>(M));
841 (
const_cast<MAT &
>(M))(i, i) = W[i];
850 template<
typename MAT>
863 template<
typename MAT,
typename VECT>
875 template<
typename VECT1,
typename VECT2>
877 const mesh_fem &mf_data,
const VECT2 &F,
879 GMM_ASSERT1(mf_data.
get_qdim() == 1 ||
881 "invalid data mesh fem (same Qdim or Qdim=1 required)");
882 asm_real_or_complex_1_param_vec
883 (
const_cast<VECT1 &
>(B), mim, mf, &mf_data, F, rg,
"A:Test_u");
891 template<
typename VECT1,
typename VECT2>
895 asm_real_or_complex_1_param_vec
896 (
const_cast<VECT1 &
>(B), mim, mf, 0, F, rg,
"A:Test_u");
903 template<
typename VECT1,
typename VECT2>
906 const mesh_fem &mf_data,
const VECT2 &F,
908 asm_real_or_complex_1_param_vec(B, mim, mf, &mf_data, F, rg,
909 "(Reshape(A, qdim(u), meshdim).Normal):Test_u");
916 template<
typename VECT1,
typename VECT2>
920 { asm_real_or_complex_1_param_vec(B, mim, mf, 0,F,rg,
921 "(Reshape(A, qdim(u), meshdim).Normal):Test_u"); }
942 template<
typename MAT,
typename VECT>
944 const mesh_fem &mf_d,
const VECT &Q,
947 asm_real_or_complex_1_param_mat
948 (M, mim,mf_u,&mf_d,Q,rg,
"(Reshape(A,qdim(u),qdim(u)).Test_u):Test2_u");
950 asm_real_or_complex_1_param_mat
951 (M, mim, mf_u, &mf_d, Q, rg,
"(A*Test_u):Test2_u");
952 else GMM_ASSERT1(
false,
"invalid data mesh fem");
955 template<
typename MAT,
typename VECT>
956 void asm_homogeneous_qu_term(MAT &M,
const mesh_im &mim,
957 const mesh_fem &mf_u,
const VECT &Q,
958 const mesh_region &rg) {
959 if (gmm::vect_size(Q) == 1)
960 asm_real_or_complex_1_param_mat
961 (M, mim,mf_u,0,Q,rg,
"(A*Test_u):Test2_u");
963 asm_real_or_complex_1_param_mat
964 (M, mim,mf_u,0,Q,rg,
"(Reshape(A,qdim(u),qdim(u)).Test_u):Test2_u");
971 template<
class MAT,
class VECT>
974 const mesh_fem &mf_data,
const VECT &LAMBDA,
const VECT &MU,
976 ga_workspace workspace;
977 gmm::sub_interval Iu(0, mf.
nb_dof());
978 base_vector u(mf.
nb_dof()), lambda(gmm::vect_size(LAMBDA));
979 base_vector mu(gmm::vect_size(MU));
980 gmm::copy(LAMBDA, lambda); gmm::copy(MU, mu);
981 workspace.add_fem_variable(
"u", mf, Iu, u);
982 workspace.add_fem_constant(
"lambda", mf_data, lambda);
983 workspace.add_fem_constant(
"mu", mf_data, mu);
984 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)"
985 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
986 workspace.assembly(2);
987 if (gmm::mat_nrows(workspace.assembled_matrix()))
988 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
992 (model_real_sparse_matrix &M,
const mesh_im &mim,
const mesh_fem &mf,
993 const mesh_fem &mf_data,
const model_real_plain_vector &LAMBDA,
994 const model_real_plain_vector &MU,
996 ga_workspace workspace;
997 gmm::sub_interval Iu(0, mf.nb_dof());
998 base_vector u(mf.nb_dof());
999 workspace.add_fem_variable(
"u", mf, Iu, u);
1000 workspace.add_fem_constant(
"lambda", mf_data, LAMBDA);
1001 workspace.add_fem_constant(
"mu", mf_data, MU);
1002 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)"
1003 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
1004 workspace.set_assembled_matrix(M);
1005 workspace.assembly(2);
1013 template<
class MAT,
class VECT>
1016 const VECT &LAMBDA,
const VECT &MU,
1018 ga_workspace workspace;
1019 gmm::sub_interval Iu(0, mf.
nb_dof());
1020 base_vector u(mf.
nb_dof()), lambda(gmm::vect_size(LAMBDA));
1021 base_vector mu(gmm::vect_size(MU));
1022 gmm::copy(LAMBDA, lambda); gmm::copy(MU, mu);
1023 workspace.add_fem_variable(
"u", mf, Iu, u);
1024 workspace.add_fixed_size_constant(
"lambda", lambda);
1025 workspace.add_fixed_size_constant(
"mu", mu);
1026 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)"
1027 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
1028 workspace.assembly(2);
1029 if (gmm::mat_nrows(workspace.assembled_matrix()))
1030 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
1035 (model_real_sparse_matrix &M,
const mesh_im &mim,
const mesh_fem &mf,
1036 const model_real_plain_vector &LAMBDA,
const model_real_plain_vector &MU,
1038 ga_workspace workspace;
1039 gmm::sub_interval Iu(0, mf.nb_dof());
1040 base_vector u(mf.nb_dof());
1041 workspace.add_fem_variable(
"u", mf, Iu, u);
1042 workspace.add_fixed_size_constant(
"lambda", LAMBDA);
1043 workspace.add_fixed_size_constant(
"mu", MU);
1044 workspace.add_expression(
"((lambda*Div_Test_u)*Id(meshdim)"
1045 "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
1046 workspace.set_assembled_matrix(M);
1047 workspace.assembly(2);
1060 template<
typename MAT,
typename VECT>
void
1072 template<
typename MAT>
1076 ga_workspace workspace;
1077 gmm::sub_interval Iu(0, mf_u.
nb_dof()), Ip(Iu.last(), mf_p.
nb_dof());
1079 workspace.add_fem_variable(
"u", mf_u, Iu, u);
1080 workspace.add_fem_variable(
"p", mf_p, Ip, p);
1081 workspace.add_expression(
"Test_p*Div_Test2_u", mim, rg);
1082 workspace.assembly(2);
1083 if (gmm::mat_nrows(workspace.assembled_matrix()))
1084 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(), Ip, Iu),
1085 const_cast<MAT &
>(B));
1088 inline void asm_stokes_B(model_real_sparse_matrix &B,
const mesh_im &mim,
1089 const mesh_fem &mf_u,
const mesh_fem &mf_p,
1091 ga_workspace workspace;
1092 gmm::sub_interval Iu(0, mf_u.nb_dof()), Ip(0, mf_p.nb_dof());
1093 base_vector u(mf_u.nb_dof()), p(mf_p.nb_dof());
1094 workspace.add_fem_variable(
"u", mf_u, Iu, u);
1095 workspace.add_fem_variable(
"p", mf_p, Ip, p);
1096 workspace.add_expression(
"Test_p*Div_Test2_u", mim, rg);
1097 workspace.set_assembled_matrix(B);
1098 workspace.assembly(2);
1107 template<
typename MAT>
1111 ga_workspace workspace;
1112 gmm::sub_interval Iu(0, mf.
nb_dof());
1113 base_vector u(mf.
nb_dof());
1114 workspace.add_fem_variable(
"u", mf, Iu, u);
1115 workspace.add_expression(
"Grad_Test_u:Grad_Test2_u", mim, rg);
1116 workspace.assembly(2);
1117 if (gmm::mat_nrows(workspace.assembled_matrix()))
1118 gmm::add(workspace.assembled_matrix(),
const_cast<MAT &
>(M));
1122 (model_real_sparse_matrix &M,
const mesh_im &mim,
const mesh_fem &mf,
1124 ga_workspace workspace;
1125 gmm::sub_interval Iu(0, mf.nb_dof());
1126 base_vector u(mf.nb_dof());
1127 workspace.add_fem_variable(
"u", mf, Iu, u);
1128 workspace.add_expression(
"Grad_Test_u:Grad_Test2_u", mim, rg);
1129 workspace.set_assembled_matrix(M);
1130 workspace.assembly(2);
1137 template<
typename MAT>
1149 template<
typename MAT,
typename VECT>
1153 GMM_ASSERT1(mf_data.
get_qdim() == 1
1154 && gmm::vect_size(A) == mf_data.
nb_dof(),
"invalid data");
1155 asm_real_or_complex_1_param_mat
1156 (M, mim, mf, &mf_data, A, rg,
"(A*Grad_Test_u):Grad_Test2_u");
1162 template<
typename MAT,
typename VECT>
1192 template<
typename MAT,
typename VECT>
1196 asm_real_or_complex_1_param_mat
1197 (M, mim, mf, &mf_data, A, rg,
1198 "(Reshape(A,meshdim,meshdim)*Grad_Test_u):Grad_Test2_u");
1203 template<
typename MAT,
typename VECT>
1207 asm_real_or_complex_1_param_mat
1208 (M, mim, mf, 0, A, rg,
1209 "(Reshape(A,meshdim,meshdim)*Grad_Test_u):Grad_Test2_u");
1214 template<
typename MAT,
typename VECT>
1217 const mesh_fem &mf_data,
const VECT &A,
1219 asm_real_or_complex_1_param_mat
1220 (M, mim, mf, &mf_data, A, rg,
1221 "(Grad_Test_u*(Reshape(A,meshdim,meshdim)')):Grad_Test2_u");
1226 template<
typename MAT,
typename VECT>
1230 asm_real_or_complex_1_param_mat
1231 (M, mim, mf, 0, A, rg,
1232 "(Grad_Test_u*(Reshape(A,meshdim,meshdim)')):Grad_Test2_u");
1240 template<
typename MAT,
typename VECT>
void
1245 asm_real_or_complex_1_param_mat
1246 (M, mim, mf, &mf_data, A, rg,
1247 "(Reshape(A,qdim(u),meshdim,qdim(u),meshdim):Grad_Test_u):Grad_Test2_u");
1254 template<
typename MAT,
typename VECT>
void
1259 asm_real_or_complex_1_param_mat
1260 (M, mim, mf, 0, A, rg,
1261 "(Reshape(A,qdim(u),meshdim,qdim(u),meshdim):Grad_Test_u):Grad_Test2_u");
1272 template<
typename MAT,
typename VECT>
1274 const mesh_fem &mf_data,
const VECT &K_squared,
1276 typedef typename gmm::linalg_traits<MAT>::value_type T;
1277 asm_Helmholtz_(M, mim, mf_u, &mf_data, K_squared, rg, T());
1280 template<
typename MAT,
typename VECT,
typename T>
1281 void asm_Helmholtz_(MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
1282 const mesh_fem *mf_data,
const VECT &K_squared,
1283 const mesh_region &rg, T) {
1284 asm_real_or_complex_1_param_mat
1285 (M, mim, mf_u, mf_data, K_squared, rg,
1286 "(A*Test_u).Test2_u - Grad_Test_u:Grad_Test2_u");
1289 template<
typename MAT,
typename VECT,
typename T>
1290 void asm_Helmholtz_(MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
1291 const mesh_fem *mf_data,
const VECT &K_squared,
1292 const mesh_region &rg, std::complex<T>) {
1301 ga_workspace workspace;
1302 gmm::sub_interval Iur(0, mf_u.nb_dof()), Iui(Iur.last(), mf_u.nb_dof());
1303 base_vector u(mf_u.nb_dof());
1304 base_vector AR(gmm::vect_size(K_squared)), AI(gmm::vect_size(K_squared));
1305 gmm::copy(gmm::real_part(K_squared), AR);
1306 gmm::copy(gmm::imag_part(K_squared), AI);
1307 workspace.add_fem_variable(
"u", mf_u, Iur, u);
1308 workspace.add_fem_variable(
"ui", mf_u, Iui, u);
1311 workspace.add_fem_constant(
"A", *mf_data, AR);
1312 workspace.add_fem_constant(
"AI", *mf_data, AI);
1314 workspace.add_fixed_size_constant(
"A", AR);
1315 workspace.add_fixed_size_constant(
"AI", AI);
1317 workspace.add_expression(
"(A*Test_u).Test2_u - Grad_Test_u:Grad_Test2_u",
1319 workspace.add_expression(
"(AI*Test_ui).Test2_ui", mim, rg);
1320 workspace.assembly(2);
1322 if (gmm::mat_nrows(workspace.assembled_matrix()))
1323 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(),Iur,Iur),
1324 const_cast<MAT &
>(M));
1325 if (gmm::mat_nrows(workspace.assembled_matrix()) > mf_u.nb_dof())
1326 gmm::add(gmm::sub_matrix(workspace.assembled_matrix(),Iui,Iui),
1327 gmm::imag_part(
const_cast<MAT &
>(M)));
1341 template<
typename MAT,
typename VECT>
1343 (MAT &M,
const mesh_im &mim,
const mesh_fem &mf_u,
const VECT &K_squared,
1345 typedef typename gmm::linalg_traits<MAT>::value_type T;
1346 asm_Helmholtz_(M, mim, mf_u, 0, K_squared, rg, T());
1349 enum { ASMDIR_BUILDH = 1, ASMDIR_BUILDR = 2, ASMDIR_SIMPLIFY = 4,
1350 ASMDIR_BUILDALL = 7 };
1370 template<
typename MAT,
typename VECT1,
typename VECT2>
1375 int version = ASMDIR_BUILDALL) {
1376 typedef typename gmm::linalg_traits<VECT1>::value_type value_type;
1377 typedef typename gmm::number_traits<value_type>::magnitude_type magn_type;
1379 if ((version & ASMDIR_SIMPLIFY) &&
1381 GMM_WARNING1(
"Sorry, no simplification for reduced fems");
1382 version = (version & (ASMDIR_BUILDR | ASMDIR_BUILDH));
1387 "invalid data mesh fem (Qdim=1 required)");
1388 if (version & ASMDIR_BUILDH) {
1390 gmm::clean(H, gmm::default_tol(magn_type())
1391 * gmm::mat_maxnorm(H) * magn_type(1000));
1393 if (version & ASMDIR_BUILDR)
1398 pfem pf_u, pf_r, pf_m;
1399 bool warning_msg1 =
false, warning_msg2 =
false;
1400 dal::bit_vector simplifiable_dofs, nonsimplifiable_dofs;
1401 std::vector<size_type> simplifiable_indices(mf_mult.
nb_basic_dof());
1402 std::vector<value_type> simplifiable_values(mf_mult.
nb_basic_dof());
1403 std::vector<value_type> v1, v2, v3;
1405 for (
mr_visitor v(region); !v.finished(); v.next()) {
1406 GMM_ASSERT1(v.is_face(),
"attempt to impose a dirichlet "
1407 "on the interior of the domain!");
1413 "attempt to impose a dirichlet "
1414 "condition on a convex with no FEM!");
1419 if (!pf_m->is_lagrange() && !warning_msg1) {
1420 GMM_WARNING3(
"Dirichlet condition with non-lagrange multiplier fem. "
1421 "see the documentation about Dirichlet conditions.");
1422 warning_msg1 =
true;
1425 if (!(version & ASMDIR_SIMPLIFY))
continue;
1427 mesh_fem::ind_dof_face_ct pf_u_ct
1429 mesh_fem::ind_dof_face_ct pf_r_ct
1431 mesh_fem::ind_dof_face_ct pf_m_ct
1436 size_type pf_u_nbdf_loc = pf_u->structure(cv)->nb_points_of_face(f);
1437 size_type pf_m_nbdf_loc = pf_m->structure(cv)->nb_points_of_face(f);
1440 if (pf_u_nbdf < pf_m_nbdf && !warning_msg2) {
1441 GMM_WARNING2(
"Dirichlet condition with a too rich multiplier fem. "
1442 "see the documentation about Dirichlet conditions.");
1443 warning_msg2 =
true;
1446 if (pf_u != pf_r || pf_u_nbdf != pf_m_nbdf ||
1447 ((pf_u != pf_r) && (pf_u_nbdf_loc != pf_m_nbdf_loc))) {
1448 for (
size_type i = 0; i < pf_m_nbdf; ++i)
1449 nonsimplifiable_dofs.add(pf_m_ct[i]);
1453 for (
size_type i = 0; i < pf_m_nbdf; ++i) {
1454 simplifiable_dofs.add(pf_m_ct[i]);
1455 simplifiable_indices[pf_m_ct[i]] = pf_u_ct[i];
1458 if (!(version & ASMDIR_BUILDR))
continue;
1462 for (
size_type i = 0; i < pf_m_nbdf; ++i) {
1463 simplifiable_values[pf_m_ct[i]]
1464 = r_data[pf_r_ct[i/Qratio]*Qratio+(i%Qratio)];
1469 if (version & ASMDIR_SIMPLIFY) {
1470 if (simplifiable_dofs.card() > 0)
1471 { GMM_TRACE3(
"Simplification of the Dirichlet condition"); }
1473 GMM_TRACE3(
"Sorry, no simplification of the Dirichlet condition");
1474 if (nonsimplifiable_dofs.card() > 0 && simplifiable_dofs.card() > 0)
1475 GMM_WARNING3(
"Partial simplification of the Dirichlet condition");
1477 for (dal::bv_visitor i(simplifiable_dofs); !i.finished(); ++i)
1478 if (!(nonsimplifiable_dofs[i])) {
1479 if (version & ASMDIR_BUILDH) {
1481 for (
size_type j = 0; j < cv_ct.size(); ++j) {
1486 H(i, simplifiable_indices[i]) = value_type(1);
1488 if (version & ASMDIR_BUILDR) R[i] = simplifiable_values[i];
1493 template<
typename MATRM,
typename VECT1,
typename VECT2>
1494 void assembling_Dirichlet_condition
1499 GMM_ASSERT1(!(mf.
is_reduced()),
"This function is not adapted to "
1500 "reduced finite element methods");
1503 for (dal::bv_visitor cv(mf.
convex_index()); !cv.finished(); ++cv) {
1509 if (nndof.is_in(dof1) && pf1->dof_types()[i] == ldof) {
1515 if (!(nndof.is_in(dof2)) &&
1518 B[dof2+k] -= RM(dof2+k, dof1+l) * F[dof1+l];
1519 RM(dof2+k, dof1+l) = RM(dof1+l, dof2+k) = 0;
1523 { RM(dof1+k, dof1+k) = 1; B[dof1+k] = F[dof1+k]; }
1547 template<
typename MAT,
typename VECT1,
typename VECT2,
typename VECT3>
1552 int version = ASMDIR_BUILDALL) {
1555 if ((version & ASMDIR_SIMPLIFY) &&
1557 GMM_WARNING1(
"Sorry, no simplification for reduced fems");
1558 version = (version & ASMDIR_BUILDR);
1563 "invalid data mesh fem (Qdim=1 required)");
1564 if (version & ASMDIR_BUILDH) {
1566 std::vector<size_type> ind(0);
1570 if (!(bdof[i])) ind.push_back(i);
1571 gmm::clear(gmm::sub_matrix(H, gmm::sub_index(ind)));
1573 if (version & ASMDIR_BUILDR)
1575 if (!(version & ASMDIR_SIMPLIFY))
return;
1578 if (&mf_r == &mf_h) {
1579 for (
mr_visitor v(region); !v.finished(); v.next()) {
1585 "attempt to impose a dirichlet "
1586 "condition on a convex with no FEM!");
1596 for (
size_type i = 0; i < cvs_u->nb_points_of_face(f); ++i) {
1600 size_type ind_u = cvs_u->ind_points_of_face(f)[i];
1603 for (
size_type j = 0; j < cvs_rh->nb_points_of_face(f); ++j) {
1604 size_type ind_rh = cvs_rh->ind_points_of_face(f)[j];
1616 if (tdof_u == tdof_rh &&
1617 gmm::vect_dist2_sqr((*(pf_u->node_tab(cv)))[ind_u],
1618 (*(pf_rh->node_tab(cv)))[ind_rh])
1625 if (version & ASMDIR_BUILDH)
1631 if (version & ASMDIR_BUILDH)
1632 for (
unsigned jj=0; jj < Q; jj++) {
1635 H(dof_u, dof_u2) = h_data[(jj*Q+q) + Q*Q*(dof_rh)];
1637 if (version & ASMDIR_BUILDR) R[dof_u] = r_data[dof_rh*Q+q];
1654 template<
typename MAT1,
typename MAT2,
typename VECT1,
typename VECT2>
1656 const VECT1 &R, VECT2 &U0) {
1658 typedef typename gmm::linalg_traits<MAT1>::value_type T;
1659 typedef typename gmm::number_traits<T>::magnitude_type MAGT;
1660 typedef typename gmm::temporary_vector<MAT1>::vector_type TEMP_VECT;
1661 MAGT tol = gmm::default_tol(MAGT());
1662 MAGT norminfH = gmm::mat_maxnorm(H);
1663 size_type nbd = gmm::mat_ncols(H), nbase = 0, nbr = gmm::mat_nrows(H);
1664 TEMP_VECT aux(nbr), e(nbd), f(nbd);
1670 if (!(gmm::is_col_matrix(H)))
1671 GMM_WARNING2(
"Dirichlet_nullspace inefficient for a row matrix H");
1676 gmm::clear(e); e[i] = T(1);
1677 gmm::mult(H, e, aux);
1678 MAGT n = gmm::vect_norm2(aux);
1680 if (n < norminfH*tol*1000) {
1681 NS(i, nbase++) = T(1); nn[i] =
true;
1686 if (gmm::abs(gmm::vect_sp(aux, base_img[j])) > MAGT(0))
1687 { good =
false;
break; }
1690 gmm::scale(f, T(MAGT(1)/n)); gmm::scale(aux, T(MAGT(1)/n));
1691 base_img_inv[nb_bimg] = TEMP_VECT(nbd);
1692 gmm::copy(f, base_img_inv[nb_bimg]);
1693 gmm::clean(aux, gmm::vect_norminf(aux)*tol);
1694 base_img[nb_bimg] = TEMP_VECT(nbr);
1695 gmm::copy(aux, base_img[nb_bimg++]);
1704 gmm::clear(e); e[i] = T(1); gmm::clear(f); f[i] = T(1);
1705 gmm::mult(H, e, aux);
1706 for (
size_type j = 0; j < nb_bimg; ++j) {
1707 T c = gmm::vect_sp(aux, base_img[j]);
1710 gmm::add(gmm::scaled(base_img[j], -c), aux);
1711 gmm::add(gmm::scaled(base_img_inv[j], -c), f);
1714 if (gmm::vect_norm2(aux) < norminfH*tol*MAGT(10000)) {
1715 gmm::copy(f, gmm::mat_col(NS, nbase++));
1718 MAGT n = gmm::vect_norm2(aux);
1719 gmm::scale(f, T(MAGT(1)/n)); gmm::scale(aux, T(MAGT(1)/n));
1720 gmm::clean(f, tol*gmm::vect_norminf(f));
1721 gmm::clean(aux, tol*gmm::vect_norminf(aux));
1722 base_img_inv[nb_bimg] = TEMP_VECT(nbd);
1723 gmm::copy(f, base_img_inv[nb_bimg]);
1724 base_img[nb_bimg] = TEMP_VECT(nbr);
1725 gmm::copy(aux, base_img[nb_bimg++]);
1731 for (
size_type i = 0; i < nb_bimg; ++i) {
1732 T c = gmm::vect_sp(base_img[i], R);
1733 gmm::add(gmm::scaled(base_img_inv[i], c), U0);
1736 for (
size_type i = nb_triv_base; i < nbase; ++i) {
1737 for (
size_type j = nb_triv_base; j < i; ++j) {
1738 T c = gmm::vect_sp(gmm::mat_col(NS,i), gmm::mat_col(NS,j));
1740 gmm::add(gmm::scaled(gmm::mat_col(NS,j), -c), gmm::mat_col(NS,i));
1742 gmm::scale(gmm::mat_col(NS,i),
1743 T(1) / gmm::vect_norm2(gmm::mat_col(NS,i)));
1746 for (
size_type j = nb_triv_base; j < nbase; ++j) {
1747 T c = gmm::vect_sp(gmm::mat_col(NS,j), U0);
1749 gmm::add(gmm::scaled(gmm::mat_col(NS,j), -c), U0);
1752 gmm::mult(H, U0, gmm::scaled(R, T(-1)), aux);
1753 if (gmm::vect_norm2(aux) > gmm::vect_norm2(U0)*tol*MAGT(10000))
1754 GMM_WARNING2(
"Dirichlet condition not well inverted: residu="
1755 << 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.