GetFEM  5.5
getfem_linearized_plates.cc
1 /*===========================================================================
2 
3  Copyright (C) 2004-2026 Yves Renard, Jeremie Lasry, Mathieu Fabre
4 
5  This file is a part of GetFEM
6 
7  GetFEM is free software; you can redistribute it and/or modify it
8  under the terms of the GNU Lesser General Public License as published
9  by the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version along with the GCC Runtime Library
11  Exception either version 3.1 or (at your option) any later version.
12  This program is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15  License and GCC Runtime Library Exception for more details.
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see https://www.gnu.org/licenses/.
18 
19 ===========================================================================*/
20 
21 
23 
24 
25 namespace getfem {
26 
28  const mesh_im & mim,
29  const mesh_im & mim_red,
30  const std::string &U,
31  const std::string &Theta,
32  const std::string &param_E,
33  const std::string &param_nu,
34  const std::string &param_epsilon,
35  const std::string &param_kappa,
36  size_type variant,
37  size_type region) {
38 
39 
40  std::string test_U = "Test_" + sup_previous_and_dot_to_varname(U);
41  std::string test_Theta = "Test_" + sup_previous_and_dot_to_varname(Theta);
42  std::string proj_Theta = (variant == 2) ?
43  ("Elementary_transformation("+Theta+",_2D_rotated_RT0_projection__434)")
44  : Theta;
45  std::string proj_test_Theta = (variant == 2) ?
46  ("Elementary_transformation("+test_Theta
47  +",_2D_rotated_RT0_projection__434)") : test_Theta;
48 
49  std::string D = "(("+param_E+")*pow("+param_epsilon+
50  ",3))/(12*(1-sqr("+param_nu+")))";
51  std::string G = "(("+param_E+")*("+param_epsilon+"))*("+param_kappa+
52  ")/(2*(1+("+param_nu+")))";
53  std::string E_theta = "(Grad_" + Theta + "+(Grad_" + Theta + ")')/2";
54  std::string E_test_Theta="(Grad_"+test_Theta+"+(Grad_"+test_Theta+")')/2";
55 
56  std::string expr_left =
57  D+"*(( 1-("+param_nu+"))*("+E_theta+"):("+E_test_Theta+")+("+param_nu+
58  ")*Trace("+E_theta+")*Trace("+E_test_Theta+"))";
59 
60  std::string expr_right =
61  "("+G+")*(Grad_"+U+"-"+proj_Theta+").Grad_"+test_U+
62  "-("+G+")*(Grad_"+U+"-"+proj_Theta+")."+proj_test_Theta;
63 
64  switch(variant) {
65  case 0: // Without reduction
66  return add_linear_term
67  (md, mim, expr_left+"+"+expr_right, region, false, false,
68  "Reissner-Mindlin plate model brick");
69  case 1: // With reduced integration
71  (md, mim, expr_left, region, false, false,
72  "Reissner-Mindlin plate model brick, rotation term");
73  return add_linear_term
74  (md, mim_red, expr_right, region, false, false,
75  "Reissner-Mindlin plate model brick, transverse shear term");
76  case 2: // Variant with projection on rotated RT0
77  add_2D_rotated_RT0_projection(md, "_2D_rotated_RT0_projection__434");
78  return add_linear_term
79  (md, mim, expr_left+"+"+expr_right, region, false, false,
80  "Reissner-Mindlin plate model brick");
81  break;
82  default: GMM_ASSERT1(false, "Invalid variant for Reissner-Mindlin brick.");
83  }
84  return size_type(-1);
85  }
86 
87 
89  const mesh_im & mim,
90  const mesh_im & mim_red1,
91  const mesh_im & mim_red2,
92  const std::string &Ua,
93  const std::string &Theta,
94  const std::string &U3,
95  const std::string &Theta3,
96  const std::string &param_E,
97  const std::string &param_nu,
98  const std::string &param_epsilon,
99  size_type variant,
100  size_type region) {
101 
102  std::string test_Ua = "Test_" + sup_previous_and_dot_to_varname(Ua);
103  std::string test_U3 = "Test_" + sup_previous_and_dot_to_varname(U3);
104  std::string test_Theta = "Test_" + sup_previous_and_dot_to_varname(Theta);
105  std::string proj_Theta = (variant >= 2) ?
106  ("Elementary_transformation("+Theta+",_2D_rotated_RT0_projection__434)")
107  : Theta;
108  std::string proj_test_Theta = (variant >= 2) ?
109  ("Elementary_transformation("+test_Theta+",_2D_rotated_RT0_projection__434)")
110  : test_Theta;
111  std::string test_Theta3 = "Test_" + sup_previous_and_dot_to_varname(Theta3);
112  std::string proj_Theta3 = (variant == 3) ?
113  ("Elementary_transformation("+Theta3+",_P0_projection__434)")
114  : Theta3;
115  std::string proj_test_Theta3 = (variant == 3) ?
116  ("Elementary_transformation("+test_Theta3+",_P0_projection__434)")
117  : test_Theta3;
118  std::string D1 = "(("+param_E+")*pow("+param_epsilon+",3))/(12*(1+("+param_nu+")))";
119  std::string D2 = D1+"*("+param_nu+")/(1-2*("+param_nu+"))";
120  std::string D3 = D1+"/2";
121  std::string G1 = "(("+param_E+")*("+param_epsilon+"))/(1+("+param_nu+"))";
122  std::string G2 = G1+"*("+param_nu+")/(1-2*("+param_nu+"))";
123  std::string G3 = G1+"/2";
124 
125  std::string E_Ua = "(Grad_" + Ua + "+(Grad_" + Ua + ")')/2";
126  std::string E_test_Ua = "(Grad_" + test_Ua + "+(Grad_" + test_Ua + ")')/2";
127  std::string E_Theta = "(Grad_" + Theta + "+(Grad_" + Theta + ")')/2";
128  std::string E_test_Theta="(Grad_"+test_Theta+"+(Grad_"+test_Theta+")')/2";
129 
130  std::string expr_no_coupled_1 = G1+"*("+E_Ua+"):("+E_test_Ua+") + "+G1+"*("+Theta3+")*("+test_Theta3+")";
131  std::string expr_no_coupled_2 = D1+"*("+E_Theta+"):("+E_test_Theta+") + "+D2+"*Trace(Grad_"+Theta+")*Trace(Grad_"+test_Theta+") + "+D3+"*(Grad_"+Theta3+").(Grad_"+test_Theta3+")";
132 
133  std::string expr_coupled_1 = G3+"*(Grad_"+U3+" + "+proj_Theta+").(Grad_"+test_U3+" + "+proj_test_Theta+")";
134  std::string expr_coupled_2 = G2+"*(Trace("+E_Ua+") + "+proj_Theta3+")*(Trace("+E_test_Ua+") + "+proj_test_Theta3+")";
135 
136  switch(variant) {
137  case 0: // Without reduction
139  (md, mim, expr_no_coupled_1+"+"+expr_no_coupled_2, region, false, false,
140  "enriched Reissner-Mindlin plate model brick, no coupled");
141  return add_nonlinear_term
142  (md, mim, expr_coupled_1+"+"+expr_coupled_2, region, false, false,
143  "enriched Reissner-Mindlin plate model brick, coupled");
144  case 1: // With reduced integration
146  (md, mim, expr_no_coupled_1+"+"+expr_no_coupled_2, region, false, false,
147  "enriched Reissner-Mindlin plate model brick, no coupled");
149  (md, mim_red1, expr_coupled_1, region, false, false,
150  "enriched Reissner-Mindlin plate model brick, coupled MR");
151  return add_nonlinear_term
152  (md, mim_red2, expr_coupled_2, region, false, false,
153  "enriched Reissner-Mindlin plate model brick, coupled eMR");
154  case 2: // Variant with projection on rotated RT0 and reduction
155  add_2D_rotated_RT0_projection(md, "_2D_rotated_RT0_projection__434");
157  (md, mim, expr_no_coupled_1+"+"+expr_no_coupled_2, region, false, false,
158  "enriched Reissner-Mindlin plate model brick, no coupled");
160  (md, mim, expr_coupled_1, region, false, false,
161  "enriched Reissner-Mindlin plate model brick, coupled MR");
162  return add_nonlinear_term
163  (md, mim_red2, expr_coupled_2, region, false, false,
164  "enriched Reissner-Mindlin plate model brick, coupled eMR");
165  case 3: // Variant with projection on rotated RT0 and projection P0
166  add_2D_rotated_RT0_projection(md, "_2D_rotated_RT0_projection__434");
167  add_P0_projection(md, "_P0_projection__434");
169  (md, mim, expr_no_coupled_1+"+"+expr_no_coupled_2, region, false, false,
170  "enriched Reissner-Mindlin plate model brick, no coupled");
172  (md, mim, expr_coupled_1, region, false, false,
173  "enriched Reissner-Mindlin plate model brick, coupled MR");
174  return add_nonlinear_term
175  (md, mim, expr_coupled_2, region, false, false,
176  "enriched Reissner-Mindlin plate model brick, coupled eMR");
177  break;
178  default: GMM_ASSERT1(false, " testInvalid variant for enriched Reissner-Mindlin brick.");
179  }
180  return size_type(-1);
181  }
182 
183 
184 
185 
186 
187 
188 
189 
190  // For the moment, only projection onto rotated RT0 element in dimension 2
191 
192  class _2D_Rotated_RT0_projection_transformation
193  : public virtual_elementary_transformation {
194 
195  public:
196 
197  virtual void give_transformation(const mesh_fem &mf, const mesh_fem &mf2,
198  size_type cv, base_matrix &M) const{
199 
200  THREAD_SAFE_STATIC base_matrix M_old;
201  THREAD_SAFE_STATIC pfem pf_old = nullptr;
202 
203  GMM_ASSERT1(&mf == &mf2,
204  "This transformation works on identical fems only");
205 
206  // Obtaining the fem descriptors
207  pfem pf1 = mf.fem_of_element(cv);
208  size_type N = 2;
209  GMM_ASSERT1(pf1->dim() == 2, "This projection is only defined "
210  "for two-dimensional elements");
211  size_type qmult = N / pf1->target_dim();
212 
213  bool simplex = false;
214  if (pf1->ref_convex(cv) == bgeot::simplex_of_reference(dim_type(N))) {
215  simplex = true;
216  } else if (pf1->ref_convex(cv)
217  == bgeot::parallelepiped_of_reference(dim_type(N))) {
218  simplex = false;
219  } else {
220  GMM_ASSERT1(false, "Cannot adapt the method for such an element.");
221  }
222 
223  if (pf1 == pf_old && pf1->is_equivalent() && M.size() == M_old.size()) {
224  gmm::copy(M_old, M);
225  return;
226  }
227 
228  std::stringstream fem_desc;
229  fem_desc << "FEM_RT0" << (simplex ? "":"Q") << "(" << N << ")";
230  pfem pf2 = fem_descriptor(fem_desc.str());
231 
232  // Obtaining a convenient integration method
233  size_type degree = pf1->estimated_degree() + pf2->estimated_degree();
234  bgeot::pgeometric_trans pgt = mf.linked_mesh().trans_of_convex(cv);
235  papprox_integration pim
236  = classical_approx_im(pgt, dim_type(degree))->approx_method();
237 
238  // Computation of mass matrices
239  size_type ndof1 = pf1->nb_dof(cv) * qmult;
240  size_type ndof2 = pf2->nb_dof(0);
241  base_matrix M1(ndof1, ndof1), M2(ndof2, ndof2), B(ndof1, ndof2);
242  base_matrix aux0(ndof1, ndof1), aux1(ndof1, ndof2), aux2(ndof1, ndof2);
243  base_matrix aux3(ndof2, ndof2);
244 
245 
246  base_matrix G;
247  bgeot::vectors_to_base_matrix(G, mf.linked_mesh().points_of_convex(cv));
248  fem_interpolation_context ctx1(pgt, pf1, base_node(N), G, cv);
249  fem_interpolation_context ctx2(pgt, pf2, base_node(N), G, cv);
250 
251  base_tensor t1, t2;
252  base_matrix tv1, tv2;
253 
254  for (size_type i = 0; i < pim->nb_points_on_convex(); ++i) {
255 
256  scalar_type coeff = pim->coeff(i); // Mult by ctx.J() not useful here
257  ctx1.set_xref(pim->point(i));
258  ctx2.set_xref(pim->point(i));
259  pf1->real_base_value(ctx1, t1);
260  vectorize_base_tensor(t1, tv1, ndof1, pf1->target_dim(), N);
261  pf2->real_base_value(ctx2, t2);
262  vectorize_base_tensor(t2, tv2, ndof2, pf2->target_dim(), N);
263  for (size_type j = 0; j < ndof2; ++j) std::swap(tv2(j,0), tv2(j,1));
264 
265  gmm::mult(tv1, gmm::transposed(tv1), aux0);
266  gmm::add(gmm::scaled(aux0, coeff), M1);
267  gmm::mult(tv2, gmm::transposed(tv2), aux3);
268  gmm::add(gmm::scaled(aux3, coeff), M2);
269  gmm::mult(tv1, gmm::transposed(tv2), aux1);
270  gmm::add(gmm::scaled(aux1, coeff), B);
271  }
272 
273 
274  // Computation of M
275  gmm::lu_inverse(M1);
276  gmm::lu_inverse(M2);
277  gmm::mult(M1, B, aux1);
278  gmm::mult(aux1, M2, aux2);
279  GMM_ASSERT1(gmm::mat_nrows(M) == ndof1,
280  "Element not convenient for projection");
281  gmm::mult(aux2, gmm::transposed(B), M);
282  gmm::clean(M, 1E-15);
283  M_old = M; pf_old = pf1;
284  }
285  };
286 
287  void add_2D_rotated_RT0_projection(model &md, std::string name) {
288  pelementary_transformation
289  p = std::make_shared<_2D_Rotated_RT0_projection_transformation>();
290  md.add_elementary_transformation(name, p);
291  }
292 
293 
294 
295  // Can be simplified ...
296  class _P0_projection_transformation
297  : public virtual_elementary_transformation {
298 
299  public:
300 
301  virtual void give_transformation(const mesh_fem &mf, const mesh_fem &mf2,
302  size_type cv, base_matrix &M) const{
303 
304  THREAD_SAFE_STATIC base_matrix M_old;
305  THREAD_SAFE_STATIC pfem pf_old = nullptr;
306 
307  GMM_ASSERT1(&mf == &mf2,
308  "This transformation works on identical fems only");
309 
310  // Obtaining the fem descriptors
311  pfem pf1 = mf.fem_of_element(cv);
312  size_type N = mf.get_qdim(), d = pf1->dim();
313  // GMM_ASSERT1(pf1->dim() == 2, "This projection is only defined "
314  // "for two-dimensional elements");
315  size_type qmult = N / pf1->target_dim();
316 
317  bool simplex = false;
318  if (pf1->ref_convex(cv) == bgeot::simplex_of_reference(dim_type(d))) {
319  simplex = true;
320  } else if (pf1->ref_convex(cv)
321  == bgeot::parallelepiped_of_reference(dim_type(d))) {
322  simplex = false;
323  } else {
324  GMM_ASSERT1(false, "Cannot adapt the method for such an element.");
325  }
326 
327  if (pf1 == pf_old && pf1->is_equivalent() && M.size() == M_old.size()) {
328  gmm::copy(M_old, M);
329  return;
330  }
331 
332  std::stringstream fem_desc;
333  fem_desc << "FEM_" << (simplex ? "PK":"QK") << "(" << d << "," << 0 << ")";
334  pfem pf2 = fem_descriptor(fem_desc.str());
335 
336  // Obtaining a convenient integration method
337  size_type degree = pf1->estimated_degree() + pf2->estimated_degree();
338  bgeot::pgeometric_trans pgt = mf.linked_mesh().trans_of_convex(cv);
339  papprox_integration pim
340  = classical_approx_im(pgt, dim_type(degree))->approx_method();
341 
342  // Computation of mass matrices
343  size_type ndof1 = pf1->nb_dof(cv) * qmult;
344  size_type ndof2 = pf2->nb_dof(0) * qmult;
345  base_matrix M1(ndof1, ndof1), M2(ndof2, ndof2), B(ndof1, ndof2);
346  base_matrix aux0(ndof1, ndof1), aux1(ndof1, ndof2), aux2(ndof1, ndof2);
347  base_matrix aux3(ndof2, ndof2);
348 
349 
350  base_matrix G;
351  bgeot::vectors_to_base_matrix(G, mf.linked_mesh().points_of_convex(cv));
352  fem_interpolation_context ctx1(pgt, pf1, base_node(d), G, cv);
353  fem_interpolation_context ctx2(pgt, pf2, base_node(d), G, cv);
354 
355  base_tensor t1, t2;
356  base_matrix tv1, tv2;
357 
358  for (size_type i = 0; i < pim->nb_points_on_convex(); ++i) {
359 
360  scalar_type coeff = pim->coeff(i); // Mult by ctx.J() not useful here
361  ctx1.set_xref(pim->point(i));
362  ctx2.set_xref(pim->point(i));
363  pf1->real_base_value(ctx1, t1);
364  vectorize_base_tensor(t1, tv1, ndof1, pf1->target_dim(), N);
365  pf2->real_base_value(ctx2, t2);
366  vectorize_base_tensor(t2, tv2, ndof2, pf2->target_dim(), N);
367  // for (size_type j = 0; j < ndof2; ++j) std::swap(tv2(j,0), tv2(j,1));
368 
369  gmm::mult(tv1, gmm::transposed(tv1), aux0);
370  gmm::add(gmm::scaled(aux0, coeff), M1);
371  gmm::mult(tv2, gmm::transposed(tv2), aux3);
372  gmm::add(gmm::scaled(aux3, coeff), M2);
373  gmm::mult(tv1, gmm::transposed(tv2), aux1);
374  gmm::add(gmm::scaled(aux1, coeff), B);
375  }
376 
377 
378  // Computation of M
379  gmm::lu_inverse(M1);
380  gmm::lu_inverse(M2);
381  gmm::mult(M1, B, aux1);
382  gmm::mult(aux1, M2, aux2);
383  GMM_ASSERT1(gmm::mat_nrows(M) == ndof1,
384  "Element not convenient for projection");
385  gmm::mult(aux2, gmm::transposed(B), M);
386  gmm::clean(M, 1E-15);
387  M_old = M; pf_old = pf1;
388  }
389  };
390 
391 
392 
393 
394  void add_P0_projection(model &md, std::string name) {
395  pelementary_transformation
396  p = std::make_shared<_P0_projection_transformation>();
397  md.add_elementary_transformation(name, p);
398  }
399 
400 
401 
402 
403  // RT0 projection in any dimension. Unused for the moment.
404 
405 
406 // class RT0_projection_transformation
407 // : public virtual_elementary_transformation {
408 
409 // public:
410 
411 // virtual void give_transformation(const mesh_fem &mf, size_type cv,
412 // base_matrix &M) const{
413 
414 
415 
416 // // Obtaining the fem descriptors
417 // pfem pf1 = mf.fem_of_element(cv);
418 // size_type N = pf1->dim();
419 // size_type qmult = N / pf1->target_dim();
420 
421 // bool simplex = false;
422 // if (pf1->ref_convex(cv) == bgeot::simplex_of_reference(dim_type(N))) {
423 // simplex = true;
424 // } else if (pf1->ref_convex(cv)
425 // == bgeot::parallelepiped_of_reference(dim_type(N))) {
426 // simplex = false;
427 // } else {
428 // GMM_ASSERT1(false, "Cannot adapt the method for such an element.");
429 // }
430 
431 // GMM_ASSERT1(pf1->is_equivalent(), "For tau-equivalent fem only."); // Indeed no, for the moment ...
432 
433 // std::stringstream fem_desc;
434 // fem_desc << "FEM_RT0" << (simplex ? "":"Q") << "(" << N << ")";
435 // pfem pf2 = fem_descriptor(fem_desc.str());
436 
437 // // Obtaining a convenient integration method
438 // size_type degree = pf1->estimated_degree() + pf2->estimated_degree();
439 // bgeot::pgeometric_trans pgt = mf.linked_mesh().trans_of_convex(cv);
440 // papprox_integration pim
441 // = classical_approx_im(pgt, dim_type(degree))->approx_method();
442 
443 // // Computation of mass matrices
444 // size_type ndof1 = pf1->nb_dof(cv) * qmult;
445 // size_type ndof2 = pf2->nb_dof(0);
446 // base_matrix M1(ndof1, ndof1), M2(ndof2, ndof2), B(ndof1, ndof2);
447 // base_matrix aux0(ndof1, ndof1), aux1(ndof1, ndof2), aux2(ndof1, ndof2);
448 // base_matrix aux3(ndof2, ndof2);
449 
450 
451 // base_matrix G;
452 // bgeot::vectors_to_base_matrix(G, mf.linked_mesh().points_of_convex(cv));
453 // fem_interpolation_context ctx1(pgt, pf1, base_node(N), G, cv);
454 // fem_interpolation_context ctx2(pgt, pf2, base_node(N), G, cv);
455 
456 // base_tensor t1, t2;
457 // base_matrix tv1, tv2;
458 
459 // for (size_type i = 0; i < pim->nb_points_on_convex(); ++i) {
460 
461 // scalar_type coeff = pim->coeff(i); // Mult by ctx.J() not useful here
462 // ctx1.set_xref(pim->point(i));
463 // ctx2.set_xref(pim->point(i));
464 // pf1->real_base_value(ctx1, t1);
465 // vectorize_base_tensor(t1, tv1, ndof1, pf1->target_dim(), N);
466 // pf2->real_base_value(ctx2, t2);
467 // vectorize_base_tensor(t2, tv2, ndof2, pf2->target_dim(), N);
468 
469 
470 // // for (size_type j = 0; j < 4; ++j)
471 // // std::swap(tv2(j,0), tv2(j,1));
472 
473 
474 // gmm::mult(tv1, gmm::transposed(tv1), aux0);
475 // gmm::add(gmm::scaled(aux0, coeff), M1);
476 // gmm::mult(tv2, gmm::transposed(tv2), aux3);
477 // gmm::add(gmm::scaled(aux3, coeff), M2);
478 // gmm::mult(tv1, gmm::transposed(tv2), aux1);
479 // gmm::add(gmm::scaled(aux1, coeff), B);
480 // }
481 
482 
483 // // Computation of M
484 // gmm::lu_inverse(M1);
485 // gmm::lu_inverse(M2);
486 // gmm::mult(M1, B, aux1);
487 // gmm::mult(aux1, M2, aux2);
488 // GMM_ASSERT1(gmm::mat_nrows(M) == ndof1,
489 // "Element not convenient for projection");
490 // gmm::mult(aux2, gmm::transposed(B), M);
491 // gmm::clean(M, 1E-15);
492 // // cout << "M = " << M << endl;
493 // }
494 // };
495 
496 
497 
498 
499 
500 
501 
502 
503 } /* end of namespace getfem. */
504 
Describe an integration method linked to a mesh.
`‘Model’' variables store the variables, the data and the description of a model.
void add_elementary_transformation(const std::string &name, pelementary_transformation ptrans)
Add an elementary transformation to the model to be used with the generic assembly.
Reissner-Mindlin plate model brick.
void copy(const L1 &l1, L2 &l2)
*‍/
Definition: gmm_blas.h:976
void clean(L &l, double threshold)
Clean a vector or matrix (replace near-zero entries with zeroes).
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*‍/
Definition: gmm_blas.h:1663
void add(const L1 &l1, L2 &l2)
*‍/
Definition: gmm_blas.h:1275
void lu_inverse(const DenseMatrixLU &LU, const Pvector &pvector, const DenseMatrix &AInv_)
Given an LU factored matrix, build the inverse of the matrix.
Definition: gmm_dense_lu.h:211
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Definition: getfem_fem.h:243
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
Definition: getfem_fem.cc:4659
pconvex_ref simplex_of_reference(dim_type nc, short_type K)
returns a simplex of reference of dimension nc and degree k
pconvex_ref parallelepiped_of_reference(dim_type nc, dim_type k)
parallelepiped of reference of dimension nc (and degree 1)
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:48
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
GEneric Tool for Finite Element Methods.
size_type APIDECL add_nonlinear_term(model &md, const mesh_im &mim, const std::string &expr, size_type region=size_type(-1), bool is_sym=false, bool is_coercive=false, const std::string &brickname="")
Add a nonlinear term given by the weak form language expression expr which will be assembled in regio...
pintegration_method classical_approx_im(bgeot::pgeometric_trans pgt, dim_type degree)
try to find an approximate integration method for the geometric transformation pgt which is able to i...
void add_P0_projection(model &md, std::string name)
Add the elementary transformation corresponding to the projection on P0 element.
size_type APIDECL add_linear_term(model &md, const mesh_im &mim, const std::string &expr, size_type region=size_type(-1), bool is_sym=false, bool is_coercive=false, const std::string &brickname="", bool return_if_nonlin=false)
Add a term given by the weak form language expression expr which will be assembled in region region a...
size_type add_Mindlin_Reissner_plate_brick(model &md, const mesh_im &mim, const mesh_im &mim_reduced, const std::string &u3, const std::string &Theta, const std::string &param_E, const std::string &param_nu, const std::string &param_epsilon, const std::string &param_kappa, size_type variant=size_type(2), size_type region=size_type(-1))
Add a term corresponding to the classical Reissner-Mindlin plate model for which u3 is the transverse...
void add_2D_rotated_RT0_projection(model &md, std::string name)
Add the elementary transformation corresponding to the projection on rotated RT0 element for two-dime...
size_type add_enriched_Mindlin_Reissner_plate_brick(model &md, const mesh_im &mim, const mesh_im &mim_reduced1, const mesh_im &mim_reduced2, const std::string &ua, const std::string &Theta, const std::string &u3, const std::string &Theta3, const std::string &param_E, const std::string &param_nu, const std::string &param_epsilon, size_type variant=size_type(3), size_type region=size_type(-1))
Add a term corresponding to the enriched Reissner-Mindlin plate model for which varname_ua is the mem...