31 const std::string &Theta,
32 const std::string ¶m_E,
33 const std::string ¶m_nu,
34 const std::string ¶m_epsilon,
35 const std::string ¶m_kappa,
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)")
45 std::string proj_test_Theta = (variant == 2) ?
46 (
"Elementary_transformation("+test_Theta
47 +
",_2D_rotated_RT0_projection__434)") : test_Theta;
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";
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+
"))";
60 std::string expr_right =
61 "("+G+
")*(Grad_"+U+
"-"+proj_Theta+
").Grad_"+test_U+
62 "-("+G+
")*(Grad_"+U+
"-"+proj_Theta+
")."+proj_test_Theta;
67 (md, mim, expr_left+
"+"+expr_right, region,
false,
false,
68 "Reissner-Mindlin plate model brick");
71 (md, mim, expr_left, region,
false,
false,
72 "Reissner-Mindlin plate model brick, rotation term");
74 (md, mim_red, expr_right, region,
false,
false,
75 "Reissner-Mindlin plate model brick, transverse shear term");
79 (md, mim, expr_left+
"+"+expr_right, region,
false,
false,
80 "Reissner-Mindlin plate model brick");
82 default: GMM_ASSERT1(
false,
"Invalid variant for Reissner-Mindlin brick.");
92 const std::string &Ua,
93 const std::string &Theta,
94 const std::string &U3,
95 const std::string &Theta3,
96 const std::string ¶m_E,
97 const std::string ¶m_nu,
98 const std::string ¶m_epsilon,
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)")
108 std::string proj_test_Theta = (variant >= 2) ?
109 (
"Elementary_transformation("+test_Theta+
",_2D_rotated_RT0_projection__434)")
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)")
115 std::string proj_test_Theta3 = (variant == 3) ?
116 (
"Elementary_transformation("+test_Theta3+
",_P0_projection__434)")
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";
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";
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+
")";
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+
")";
139 (md, mim, expr_no_coupled_1+
"+"+expr_no_coupled_2, region,
false,
false,
140 "enriched Reissner-Mindlin plate model brick, no coupled");
142 (md, mim, expr_coupled_1+
"+"+expr_coupled_2, region,
false,
false,
143 "enriched Reissner-Mindlin plate model brick, coupled");
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");
152 (md, mim_red2, expr_coupled_2, region,
false,
false,
153 "enriched Reissner-Mindlin plate model brick, coupled eMR");
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");
163 (md, mim_red2, expr_coupled_2, region,
false,
false,
164 "enriched Reissner-Mindlin plate model brick, coupled eMR");
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");
175 (md, mim, expr_coupled_2, region,
false,
false,
176 "enriched Reissner-Mindlin plate model brick, coupled eMR");
178 default: GMM_ASSERT1(
false,
" testInvalid variant for enriched Reissner-Mindlin brick.");
192 class _2D_Rotated_RT0_projection_transformation
193 :
public virtual_elementary_transformation {
197 virtual void give_transformation(
const mesh_fem &mf,
const mesh_fem &mf2,
200 THREAD_SAFE_STATIC base_matrix M_old;
201 THREAD_SAFE_STATIC
pfem pf_old =
nullptr;
203 GMM_ASSERT1(&mf == &mf2,
204 "This transformation works on identical fems only");
207 pfem pf1 = mf.fem_of_element(cv);
209 GMM_ASSERT1(pf1->dim() == 2,
"This projection is only defined "
210 "for two-dimensional elements");
213 bool simplex =
false;
216 }
else if (pf1->ref_convex(cv)
220 GMM_ASSERT1(
false,
"Cannot adapt the method for such an element.");
223 if (pf1 == pf_old && pf1->is_equivalent() && M.size() == M_old.size()) {
228 std::stringstream fem_desc;
229 fem_desc <<
"FEM_RT0" << (simplex ?
"":
"Q") <<
"(" << N <<
")";
233 size_type degree = pf1->estimated_degree() + pf2->estimated_degree();
235 papprox_integration pim
239 size_type ndof1 = pf1->nb_dof(cv) * qmult;
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);
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);
252 base_matrix tv1, tv2;
254 for (
size_type i = 0; i < pim->nb_points_on_convex(); ++i) {
256 scalar_type coeff = pim->coeff(i);
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));
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);
279 GMM_ASSERT1(gmm::mat_nrows(M) == ndof1,
280 "Element not convenient for projection");
283 M_old = M; pf_old = pf1;
288 pelementary_transformation
289 p = std::make_shared<_2D_Rotated_RT0_projection_transformation>();
296 class _P0_projection_transformation
297 :
public virtual_elementary_transformation {
301 virtual void give_transformation(
const mesh_fem &mf,
const mesh_fem &mf2,
304 THREAD_SAFE_STATIC base_matrix M_old;
305 THREAD_SAFE_STATIC
pfem pf_old =
nullptr;
307 GMM_ASSERT1(&mf == &mf2,
308 "This transformation works on identical fems only");
311 pfem pf1 = mf.fem_of_element(cv);
312 size_type N = mf.get_qdim(), d = pf1->dim();
317 bool simplex =
false;
320 }
else if (pf1->ref_convex(cv)
324 GMM_ASSERT1(
false,
"Cannot adapt the method for such an element.");
327 if (pf1 == pf_old && pf1->is_equivalent() && M.size() == M_old.size()) {
332 std::stringstream fem_desc;
333 fem_desc <<
"FEM_" << (simplex ?
"PK":
"QK") <<
"(" << d <<
"," << 0 <<
")";
337 size_type degree = pf1->estimated_degree() + pf2->estimated_degree();
339 papprox_integration pim
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);
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);
356 base_matrix tv1, tv2;
358 for (
size_type i = 0; i < pim->nb_points_on_convex(); ++i) {
360 scalar_type coeff = pim->coeff(i);
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);
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);
383 GMM_ASSERT1(gmm::mat_nrows(M) == ndof1,
384 "Element not convenient for projection");
387 M_old = M; pf_old = pf1;
395 pelementary_transformation
396 p = std::make_shared<_P0_projection_transformation>();
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)
*/
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)
*/
void add(const L1 &l1, L2 &l2)
*/
void lu_inverse(const DenseMatrixLU &LU, const Pvector &pvector, const DenseMatrix &AInv_)
Given an LU factored matrix, build the inverse of the matrix.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
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
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 ¶m_E, const std::string ¶m_nu, const std::string ¶m_epsilon, const std::string ¶m_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 ¶m_E, const std::string ¶m_nu, const std::string ¶m_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...