30 typedef const fem<bgeot::polynomial_composite> *
ppolycompfem;
32 struct polynomial_composite_fem :
public fem<bgeot::polynomial_composite> {
34 mutable bgeot::mesh_precomposite mp;
36 mutable bgeot::pgeotrans_precomp pgp;
38 bgeot::pstored_point_tab pspt;
41 virtual void mat_trans(base_matrix &M,
const base_matrix &G,
45 polynomial_composite_fem(
const mesh &m_,
const mesh_fem &mf_)
46 : m(m_), mp(m), mf(m), pgp(0), pgt_stored(0) {
47 for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv)
48 mf.set_finite_element(cv, mf_.fem_of_element(cv));
50 pspt = store_point_tab(m.points());
52 for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
53 pfem pf1 = mf.fem_of_element(cv);
54 if (!(pf1->is_equivalent())) {
55 dal::bit_vector unshareable;
56 for (
const auto &i : mf.ind_basic_dof_of_element(cv))
59 for (dal::bv_visitor cv2(mf.convex_index()); !cv2.finished(); ++cv2) {
61 for (
const auto &i : mf.ind_basic_dof_of_element(cv2))
62 GMM_ASSERT1(!(unshareable.is_in(i)),
"Non equivalent elements "
63 "are allowed only if they do not share their dofs");
70 void polynomial_composite_fem::mat_trans(base_matrix &M,
const base_matrix &G,
72 dim_type N = dim_type(G.nrows());
73 gmm::copy(gmm::identity_matrix(), M);
76 if (pgt != pgt_stored) {
78 pgp = bgeot::geotrans_precomp(pgt, pspt, 0);
81 for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
82 pfem pf1 = mf.fem_of_element(cv);
83 if (!(pf1->is_equivalent())) {
85 size_type ndof=mf.nb_basic_dof_of_element(cv);
86 GMM_ASSERT1(ndof == pf1->nb_base(0) && ndof == pf1->nb_dof(0),
87 "Sorry, limited implementation for the moment");
90 M1.resize(ndof, ndof);
92 gmm::copy(pgp->transform(m.ind_points_of_convex(cv)[i], G),
95 pf1->mat_trans(M1, G1, m.trans_of_convex(cv));
96 gmm::sub_index I(mf.ind_basic_dof_of_element(cv));
98 gmm::copy(M1, gmm::sub_matrix(M, I, I));
104 const mesh_fem &mf, bgeot::pconvex_ref cr,
107 GMM_ASSERT1(!mf.is_reduced(),
108 "Sorry, does not work for reduced mesh_fems");
109 auto p = std::make_shared<polynomial_composite_fem>(m, mf);
111 p->mref_convex() = cr;
112 p->dim() = cr->structure()->dim();
113 p->is_polynomialcomp() = p->is_equivalent() = p->is_standard() =
true;
114 p->is_polynomial() =
false;
115 p->is_lagrange() =
true;
116 p->estimated_degree() = 0;
119 std::vector<bgeot::polynomial_composite> base(mf.nb_basic_dof());
120 std::fill(base.begin(), base.end(),
121 bgeot::polynomial_composite(p->mp,
true, ff));
122 std::vector<pdof_description> dofd(mf.nb_basic_dof());
124 for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
125 pfem pf1 = mf.fem_of_element(cv);
126 if (!pf1->is_lagrange()) p->is_lagrange() =
false;
127 if (!(pf1->is_equivalent())) p->is_equivalent() =
false;
129 GMM_ASSERT1(pf1->is_polynomial(),
"Only for polynomial fems.");
131 p->estimated_degree() = std::max(p->estimated_degree(),
132 pf->estimated_degree());
133 for (
size_type k = 0; k < pf->nb_dof(cv); ++k) {
134 size_type igl = mf.ind_basic_dof_of_element(cv)[k];
135 base_poly fu = pf->base()[k];
136 base[igl].set_poly_of_subelt(cv, fu);
137 dofd[igl] = pf->dof_types()[k];
140 p->base().resize(mf.nb_basic_dof());
141 for (
size_type k = 0; k < mf.nb_basic_dof(); ++k) {
142 p->add_node(dofd[k], mf.point_of_basic_dof(k));
143 p->base()[k] = base[k];
148 typedef dal::naming_system<virtual_fem>::param_list fem_param_list;
150 pfem structured_composite_fem_method(fem_param_list ¶ms,
151 std::vector<dal::pstatic_stored_object> &dependencies) {
152 GMM_ASSERT1(params.size() == 2,
"Bad number of parameters : "
153 << params.size() <<
" should be 2.");
154 GMM_ASSERT1(params[0].type() == 1 && params[1].type() == 0,
155 "Bad type of parameters");
156 pfem pf = params[0].method();
157 int k = int(::floor(params[1].num() + 0.01));
158 GMM_ASSERT1(((pf->is_polynomial()) || !(pf->is_equivalent())) && k > 0
159 && k <= 150 &&
double(k) == params[1].num(),
"Bad parameters");
160 bgeot::pbasic_mesh pm;
161 bgeot::pmesh_precomposite pmp;
167 mf.set_finite_element(pm->convex_index(), pf);
168 pfem p = composite_fe_method(m, mf, pf->ref_convex(0));
169 dependencies.push_back(p->ref_convex(0));
170 dependencies.push_back(p->node_tab(0));
174 pfem PK_composite_hierarch_fem(fem_param_list ¶ms,
175 std::vector<dal::pstatic_stored_object> &) {
176 GMM_ASSERT1(params.size() == 3,
"Bad number of parameters : "
177 << params.size() <<
" should be 3.");
178 GMM_ASSERT1(params[0].type() == 0 && params[1].type() == 0 &&
179 params[2].type() == 0,
"Bad type of parameters");
180 int n = int(::floor(params[0].num() + 0.01));
181 int k = int(::floor(params[1].num() + 0.01));
182 int s = int(::floor(params[2].num() + 0.01)), t;
183 GMM_ASSERT1(n > 0 && n < 100 && k > 0 && k <= 150 && s > 0 && s <= 150 &&
184 (!(s & 1) || (s == 1)) &&
double(s) == params[2].num() &&
185 double(n) == params[0].num() &&
double(k) == params[1].num(),
187 std::stringstream name;
189 name <<
"FEM_STRUCTURED_COMPOSITE(FEM_PK(" << n <<
"," << k <<
"),1)";
191 for (t = 2; t <= s; ++t)
if ((s % t) == 0)
break;
192 name <<
"FEM_GEN_HIERARCHICAL(FEM_PK_HIERARCHICAL_COMPOSITE(" << n
193 <<
"," << k <<
"," << s/t <<
"), FEM_STRUCTURED_COMPOSITE(FEM_PK("
194 << n <<
"," << k <<
")," << s <<
"))";
199 pfem PK_composite_full_hierarch_fem(fem_param_list ¶ms,
200 std::vector<dal::pstatic_stored_object> &) {
201 GMM_ASSERT1(params.size() == 3,
"Bad number of parameters : "
202 << params.size() <<
" should be 3.");
203 GMM_ASSERT1(params[0].type() == 0 && params[1].type() == 0 &&
204 params[2].type() == 0,
"Bad type of parameters");
205 int n = int(::floor(params[0].num() + 0.01));
206 int k = int(::floor(params[1].num() + 0.01));
207 int s = int(::floor(params[2].num() + 0.01)), t;
208 GMM_ASSERT1(n > 0 && n < 100 && k > 0 && k <= 150 && s > 0 && s <= 150 &&
209 (!(s & 1) || (s == 1)) &&
double(s) == params[2].num() &&
210 double(n) == params[0].num() &&
double(k) == params[1].num(),
212 std::stringstream name;
214 name <<
"FEM_STRUCTURED_COMPOSITE(FEM_PK_HIERARCHICAL(" << n <<
","
217 for (t = 2; t <= s; ++t)
if ((s % t) == 0)
break;
218 name <<
"FEM_GEN_HIERARCHICAL(FEM_PK_FULL_HIERARCHICAL_COMPOSITE(" << n
219 <<
"," << k <<
"," << s/t
220 <<
"), FEM_STRUCTURED_COMPOSITE(FEM_PK_HIERARCHICAL("
221 << n <<
"," << k <<
")," << s <<
"))";
231 struct P1bubbletriangle__ :
public fem<bgeot::polynomial_composite> {
233 bgeot::mesh_precomposite mp;
234 P1bubbletriangle__(
void);
237 P1bubbletriangle__::P1bubbletriangle__(
void) {
240 size_type i0 = m.add_point(base_node(1.0/3.0, 1.0/3.0));
241 size_type i1 = m.add_point(base_node(0.0, 0.0));
242 size_type i2 = m.add_point(base_node(1.0, 0.0));
243 size_type i3 = m.add_point(base_node(0.0, 1.0));
249 std::stringstream s(
"1-x-y;1-x-y;1-x-y;x;x;x;y;y;y;3-3*x-3*y;3*x;3*y;");
253 dim() = cr->structure()->dim();
254 is_polynomialcomp() =
true;
255 is_equivalent() =
true;
256 is_polynomial() =
false;
257 is_lagrange() =
false;
258 is_standard() =
true;
259 estimated_degree() = 3;
262 base()=std::vector<bgeot::polynomial_composite>
263 (4, bgeot::polynomial_composite(mp,
false));
269 base_node pt(0.0, 0.0);
270 if (i) pt[i-1] = 1.0;
274 add_node(bubble1_dof(2), base_node(1.0/3.0, 1.0/3.0));
278 pfem P1bubbletriangle_fem
279 (fem_param_list ¶ms,
280 std::vector<dal::pstatic_stored_object> &dependencies) {
281 GMM_ASSERT1(params.size() == 0,
"Bad number of parameters : "
282 << params.size() <<
" should be 0.");
283 pfem p = std::make_shared<P1bubbletriangle__>();
284 dependencies.push_back(p->ref_convex(0));
285 dependencies.push_back(p->node_tab(0));
293 struct HCT_triangle__ :
public fem<bgeot::polynomial_composite> {
294 virtual void mat_trans(base_matrix &M,
const base_matrix &G,
298 mutable bgeot::mesh_precomposite mp;
299 mutable bgeot::pgeotrans_precomp pgp;
300 mutable pfem_precomp pfp;
302 mutable base_matrix K;
304 HCT_triangle__(
void);
307 void HCT_triangle__::mat_trans(base_matrix &M,
const base_matrix &G,
310 dim_type N = dim_type(G.nrows());
312 GMM_ASSERT1(N == 2,
"Sorry, this version of HCT "
313 "element works only on dimension two.");
314 if (pgt != pgt_stored) {
316 pgp = bgeot::geotrans_precomp(pgt, node_tab(0), 0);
317 pfp =
fem_precomp(std::make_shared<HCT_triangle__>(), node_tab(0), 0);
319 gmm::copy(gmm::identity_matrix(), M);
321 gmm::mult(G, pgp->grad(0), K);
323 if (i && !(pgt->is_linear())) gmm::mult(G, pgp->grad(3*i), K);
324 gmm::copy(K, gmm::sub_matrix(M, gmm::sub_interval(1+3*i, 2)));
328 static base_matrix W(3, 12);
329 base_small_vector norient(M_PI, M_PI * M_PI);
330 if (pgt->is_linear()) gmm::lu_inverse(K);
331 for (
unsigned i = 9; i < 12; ++i) {
332 if (!(pgt->is_linear()))
333 { gmm::mult(G, pgp->grad(i), K); gmm::lu_inverse(K); }
335 gmm::mult(gmm::transposed(K), cvr->normals()[i-9], n);
338 scalar_type ps = gmm::vect_sp(n, norient);
339 if (ps < 0) n *= scalar_type(-1);
340 true_normals[i-9] = n;
342 if (gmm::abs(ps) < 1E-8)
343 GMM_WARNING2(
"HCT_triangle : "
344 "The normal orientation may be not correct");
346 const bgeot::base_tensor &t = pfp->grad(i);
348 for (
unsigned j = 0; j < 12; ++j)
349 W(i-9, j) = t(j, 0, 0) * v[0] + t(j, 0, 1) * v[1];
352 static base_matrix A(3, 3);
353 static bgeot::base_vector w(3), coeff(3);
354 static gmm::sub_interval SUBI(9, 3), SUBJ(0, 3);
355 gmm::copy(gmm::sub_matrix(W, SUBJ, SUBI), A);
357 gmm::copy(gmm::transposed(A), gmm::sub_matrix(M, SUBI));
359 for (
unsigned j = 0; j < 9; ++j) {
360 gmm::mult(W, gmm::mat_row(M, j), w);
361 gmm::mult(A, gmm::scaled(w, -1.0), coeff);
362 gmm::copy(coeff, gmm::sub_vector(gmm::mat_row(M, j), SUBI));
366 HCT_triangle__::HCT_triangle__(
void) : pgt_stored(0), K(2, 2) {
369 size_type i0 = m.add_point(base_node(1.0/3.0, 1.0/3.0));
370 size_type i1 = m.add_point(base_node(0.0, 0.0));
371 size_type i2 = m.add_point(base_node(1.0, 0.0));
372 size_type i3 = m.add_point(base_node(0.0, 1.0));
380 (
"-1 + 9*x + 9*y - 15*x^2 - 30*x*y - 15*y^2 + 7*x^3 + 21*x^2*y + 21*x*y^2 + 7*y^3;"
381 "1 - 3*x^2 - 3*y^2 + 3*x^3 - 3*x^2*y + 2*y^3;"
382 "1 - 3*x^2 - 3*y^2 + 2*x^3 - 3*x*y^2 + 3*y^3;"
383 "-1/6 + 5/2*x - 9/2*x^2 - 4*x*y + 1/2*y^2 + 13/6*x^3 + 4*x^2*y + 3/2*x*y^2 - 1/3*y^3;"
384 "x - 1/2*x^2 - 3*x*y - 7/6*x^3 + 2*x^2*y + 2*x*y^2;"
385 "x - 2*x^2 - 3/2*y^2 + x^3 - 1/2*x*y^2 + 7/3*y^3;"
386 "-1/6 + 5/2*y + 1/2*x^2 - 4*x*y - 9/2*y^2 - 1/3*x^3 + 3/2*x^2*y + 4*x*y^2 + 13/6*y^3;"
387 "y - 3/2*x^2 - 2*y^2 + 7/3*x^3 - 1/2*x^2*y + y^3;"
388 "y - 3*x*y - 1/2*y^2 + 2*x^2*y + 2*x*y^2 - 7/6*y^3;"
389 "1 - 9/2*x - 9/2*y + 9*x^2 + 15*x*y + 6*y^2 - 9/2*x^3 - 21/2*x^2*y - 21/2*x*y^2 - 5/2*y^3;"
390 "3*x^2 - 5/2*x^3 + 3/2*x^2*y;"
391 "3*x^2 - 2*x^3 + 3/2*x*y^2 - 1/2*y^3;"
392 "-1/6 + 3/4*x + 3/4*y - 2*x^2 - 5/2*x*y - y^2 + 17/12*x^3 + 7/4*x^2*y + 7/4*x*y^2 + 5/12*y^3;"
393 "-x^2 + 13/12*x^3 - 1/4*x^2*y;"
394 "-x^2 + x^3 - 1/4*x*y^2 + 1/12*y^3;"
395 "2/3 - 13/4*x - 11/4*y + 9/2*x^2 + 19/2*x*y + 7/2*y^2 - 23/12*x^3 - 23/4*x^2*y - 25/4*x*y^2 - 17/12*y^3;"
396 "-1/2*x^2 + 5/12*x^3 + 9/4*x^2*y;"
397 "-x*y + 1/2*y^2 + 2*x^2*y + 7/4*x*y^2 - 13/12*y^3;"
398 "1 - 9/2*x - 9/2*y + 6*x^2 + 15*x*y + 9*y^2 - 5/2*x^3 - 21/2*x^2*y - 21/2*x*y^2 - 9/2*y^3;"
399 "3*y^2 - 1/2*x^3 + 3/2*x^2*y - 2*y^3;"
400 "3*y^2 + 3/2*x*y^2 - 5/2*y^3;"
401 "2/3 - 11/4*x - 13/4*y + 7/2*x^2 + 19/2*x*y + 9/2*y^2 - 17/12*x^3 - 25/4*x^2*y - 23/4*x*y^2 - 23/12*y^3;"
402 "1/2*x^2 - x*y - 13/12*x^3 + 7/4*x^2*y + 2*x*y^2;"
403 "-1/2*y^2 + 9/4*x*y^2 + 5/12*y^3;"
404 "-1/6 + 3/4*x + 3/4*y - x^2 - 5/2*x*y - 2*y^2 + 5/12*x^3 + 7/4*x^2*y + 7/4*x*y^2 + 17/12*y^3;"
405 "-y^2 + 1/12*x^3 - 1/4*x^2*y + y^3;"
406 "-y^2 - 1/4*x*y^2 + 13/12*y^3;"
407 "-sqrt(2)*2/3 + sqrt(2)*3*x + sqrt(2)*3*y - sqrt(2)*4*x^2 - sqrt(2)*10*x*y - sqrt(2)*4*y^2 + sqrt(2)*5/3*x^3 + sqrt(2)*7*x^2*y + sqrt(2)*7*x*y^2 + sqrt(2)*5/3*y^3;"
408 "sqrt(2)*1/3*x^3 - sqrt(2)*x^2*y;"
409 "-sqrt(2)*x*y^2 + sqrt(2)*1/3*y^3;"
410 "2/3 - 2*x - 4*y + 2*x^2 + 8*x*y + 6*y^2 - 2/3*x^3 - 4*x^2*y - 6*x*y^2 - 8/3*y^3;"
411 "2*x^2 - 4*x*y - 10/3*x^3 + 4*x^2*y + 4*x*y^2;"
412 "-2*y^2 + 2*x*y^2 + 8/3*y^3;"
413 "2/3 - 4*x - 2*y + 6*x^2 + 8*x*y + 2*y^2 - 8/3*x^3 - 6*x^2*y - 4*x*y^2 - 2/3*y^3;"
414 "-2*x^2 + 8/3*x^3 + 2*x^2*y;"
415 "-4*x*y + 2*y^2 + 4*x^2*y + 4*x*y^2 - 10/3*y^3;");
419 dim() = cr->structure()->dim();
420 is_polynomialcomp() =
true;
421 is_equivalent() =
false;
422 is_polynomial() =
false;
423 is_lagrange() =
false;
424 is_standard() =
false;
425 estimated_degree() = 5;
428 base()=std::vector<bgeot::polynomial_composite>
429 (12, bgeot::polynomial_composite(mp,
false));
435 base_node pt(0.0, 0.0);
436 if (i) pt[i-1] = 1.0;
447 pfem HCT_triangle_fem
448 (fem_param_list ¶ms,
449 std::vector<dal::pstatic_stored_object> &dependencies) {
450 GMM_ASSERT1(params.size() == 0,
"Bad number of parameters : "
451 << params.size() <<
" should be 0.");
452 pfem p = std::make_shared<HCT_triangle__>();
453 dependencies.push_back(p->ref_convex(0));
454 dependencies.push_back(p->node_tab(0));
463 struct reduced_HCT_triangle__ :
public fem<bgeot::polynomial_composite> {
464 const HCT_triangle__ *HCT;
465 virtual void mat_trans(base_matrix &M,
const base_matrix &G,
468 mutable base_matrix P, Mhct;
469 reduced_HCT_triangle__(
void);
472 void reduced_HCT_triangle__::mat_trans(base_matrix &M,
const base_matrix &G,
474 HCT->mat_trans(Mhct, G, pgt);
476 P(10, 1)=HCT->true_normals[1][0]*0.5; P(11, 1)=HCT->true_normals[2][0]*0.5;
477 P(10, 2)=HCT->true_normals[1][1]*0.5; P(11, 2)=HCT->true_normals[2][1]*0.5;
479 P( 9, 4)=HCT->true_normals[0][0]*0.5; P(11, 4)=HCT->true_normals[2][0]*0.5;
480 P( 9, 5)=HCT->true_normals[0][1]*0.5; P(11, 5)=HCT->true_normals[2][1]*0.5;
482 P( 9, 7)=HCT->true_normals[0][0]*0.5; P(10, 7)=HCT->true_normals[1][0]*0.5;
483 P( 9, 8)=HCT->true_normals[0][1]*0.5; P(10, 8)=HCT->true_normals[1][1]*0.5;
485 gmm::mult(gmm::transposed(P), Mhct, M);
488 reduced_HCT_triangle__::reduced_HCT_triangle__(
void)
489 : P(12, 9), Mhct(12, 12) {
490 HCT =
dynamic_cast<const HCT_triangle__ *
>
495 dim() = cr->structure()->dim();
496 is_polynomialcomp() =
true;
497 is_equivalent() =
false;
498 is_polynomial() =
false;
499 is_lagrange() =
false;
500 is_standard() =
false;
501 estimated_degree() = 5;
502 base() = HCT->base();
504 gmm::copy(gmm::identity_matrix(), P);
508 base_node pt(0.0, 0.0);
509 if (i) pt[i-1] = 1.0;
517 pfem reduced_HCT_triangle_fem
518 (fem_param_list ¶ms,
519 std::vector<dal::pstatic_stored_object> &dependencies) {
520 GMM_ASSERT1(params.size() == 0,
"Bad number of parameters : "
521 << params.size() <<
" should be 0.");
522 pfem p = std::make_shared<reduced_HCT_triangle__>();
523 dependencies.push_back(p->ref_convex(0));
524 dependencies.push_back(p->node_tab(0));
533 struct quadc1p3__ :
public fem<bgeot::polynomial_composite> {
534 virtual void mat_trans(base_matrix &M,
const base_matrix &G,
537 mutable bgeot::mesh_precomposite mp;
538 mutable bgeot::pgeotrans_precomp pgp;
539 mutable pfem_precomp pfp;
541 mutable base_matrix K;
546 void quadc1p3__::mat_trans(base_matrix &M,
const base_matrix &G,
549 dim_type N = dim_type(G.nrows());
551 GMM_ASSERT1(N == 2,
"Sorry, this version of reduced HCT "
552 "element works only on dimension two.");
553 if (pgt != pgt_stored) {
555 pgp = bgeot::geotrans_precomp(pgt, node_tab(0), 0);
556 pfp =
fem_precomp(std::make_shared<quadc1p3__>(), node_tab(0), 0);
558 gmm::copy(gmm::identity_matrix(), M);
560 gmm::mult(G, pgp->grad(0), K);
562 if (i && !(pgt->is_linear())) gmm::mult(G, pgp->grad(3*i), K);
563 gmm::copy(K, gmm::sub_matrix(M, gmm::sub_interval(1+3*i, 2)));
567 static base_matrix W(4, 16);
568 base_small_vector norient(M_PI, M_PI * M_PI);
569 if (pgt->is_linear()) gmm::lu_inverse(K);
570 for (
unsigned i = 12; i < 16; ++i) {
571 if (!(pgt->is_linear()))
572 { gmm::mult(G, pgp->grad(i), K); gmm::lu_inverse(K); }
574 gmm::mult(gmm::transposed(K), cvr->normals()[i-12], n);
577 scalar_type ps = gmm::vect_sp(n, norient);
578 if (ps < 0) n *= scalar_type(-1);
579 true_normals[i-12] = n;
580 if (gmm::abs(ps) < 1E-8)
581 GMM_WARNING2(
"FVS_quadrilateral : "
582 "The normal orientation may be not correct");
584 const bgeot::base_tensor &t = pfp->grad(i);
585 for (
unsigned j = 0; j < 16; ++j)
586 W(i-12, j) = t(j, 0, 0) * v[0] + t(j, 0, 1) * v[1];
589 static base_matrix A(4, 4);
590 static bgeot::base_vector w(4), coeff(4);
591 static gmm::sub_interval SUBI(12, 4), SUBJ(0, 4);
592 gmm::copy(gmm::sub_matrix(W, SUBJ, SUBI), A);
594 gmm::copy(gmm::transposed(A), gmm::sub_matrix(M, SUBI));
596 for (
unsigned j = 0; j < 12; ++j) {
597 gmm::mult(W, gmm::mat_row(M, j), w);
598 gmm::mult(A, gmm::scaled(w, -1.0), coeff);
599 gmm::copy(coeff, gmm::sub_vector(gmm::mat_row(M, j), SUBI));
603 quadc1p3__::quadc1p3__(
void) : pgt_stored(0), K(2, 2) {
606 size_type i0 = m.add_point(base_node(0.0, 0.0));
607 size_type i1 = m.add_point(base_node(1.0, 0.0));
608 size_type i2 = m.add_point(base_node(0.0, 1.0));
609 size_type i3 = m.add_point(base_node(1.0, 1.0));
610 size_type i4 = m.add_point(base_node(0.5, 0.5));
618 (
"2 - 3*x - 3*y + 6*x*y + x^3 - 3*x^2*y;"
619 "1 - 3*x^2 - 3*y^2 + x^3 + 3*x^2*y + 2*y^3;"
620 "2 - 3*x - 3*y + 6*x*y - 3*x*y^2 + y^3;"
621 "1 - 3*x^2 - 3*y^2 + 2*x^3 + 3*x*y^2 + y^3;"
622 "1/6 + 1/2*x - y - 3/2*x^2 + 2*x*y + 5/6*x^3 - x^2*y;"
623 "x - 1/2*x^2 - 3*x*y + 1/6*x^3 + x^2*y + 2*x*y^2;"
624 "1/6 + 1/2*x - y - x*y + 3/2*y^2 + 1/2*x*y^2 - 2/3*y^3;"
625 "x - 2*x^2 - 3/2*y^2 + x^3 + 3/2*x*y^2 + 2/3*y^3;"
626 "1/6 - x + 1/2*y + 3/2*x^2 - x*y - 2/3*x^3 + 1/2*x^2*y;"
627 "y - 3/2*x^2 - 2*y^2 + 2/3*x^3 + 3/2*x^2*y + y^3;"
628 "1/6 - x + 1/2*y + 2*x*y - 3/2*y^2 - x*y^2 + 5/6*y^3;"
629 "y - 3*x*y - 1/2*y^2 + 2*x^2*y + x*y^2 + 1/6*y^3;"
630 "-1 + 3*x + 3*y - 6*x*y - 3*y^2 - x^3 + 3*x^2*y + 2*y^3;"
631 "3*x^2 - x^3 - 3*x^2*y;"
632 "-1 + 3*x + 3*y - 6*x*y - 3*y^2 + 3*x*y^2 + y^3;"
633 "3*x^2 - 2*x^3 - 3*x*y^2 + y^3;"
634 "-2/3 + 1/2*x + 2*y - x*y - 2*y^2 + 1/6*x^3 - x^2*y + 2*x*y^2;"
635 "-x^2 + 5/6*x^3 + x^2*y;"
636 "-2/3 + 1/2*x + 2*y - x*y - 2*y^2 + 1/2*x*y^2 + 2/3*y^3;"
637 "-x^2 + x^3 + 3/2*x*y^2 - 2/3*y^3;"
638 "-5/6 + x + 5/2*y + 1/2*x^2 - 3*x*y - 2*y^2 - 2/3*x^3 + 3/2*x^2*y + y^3;"
639 "-1/2*x^2 + 2/3*x^3 + 1/2*x^2*y;"
640 "-5/6 + x + 5/2*y - 2*x*y - 5/2*y^2 + x*y^2 + 5/6*y^3;"
641 "-x*y + 1/2*y^2 + 2*x^2*y - x*y^2 + 1/6*y^3;"
642 "-1 + 3*x + 3*y - 3*x^2 - 6*x*y + x^3 + 3*x^2*y;"
643 "3*y^2 + x^3 - 3*x^2*y - 2*y^3;"
644 "-1 + 3*x + 3*y - 3*x^2 - 6*x*y + 2*x^3 + 3*x*y^2 - y^3;"
645 "3*y^2 - 3*x*y^2 - y^3;"
646 "-5/6 + 5/2*x + y - 5/2*x^2 - 2*x*y + 5/6*x^3 + x^2*y;"
647 "1/2*x^2 - x*y + 1/6*x^3 - x^2*y + 2*x*y^2;"
648 "-5/6 + 5/2*x + y - 2*x^2 - 3*x*y + 1/2*y^2 + x^3 + 3/2*x*y^2 - 2/3*y^3;"
649 "-1/2*y^2 + 1/2*x*y^2 + 2/3*y^3;"
650 "-2/3 + 2*x + 1/2*y - 2*x^2 - x*y + 2/3*x^3 + 1/2*x^2*y;"
651 "-y^2 - 2/3*x^3 + 3/2*x^2*y + y^3;"
652 "-2/3 + 2*x + 1/2*y - 2*x^2 - x*y + 2*x^2*y - x*y^2 + 1/6*y^3;"
653 "-y^2 + x*y^2 + 5/6*y^3;"
654 "1 - 3*x - 3*y + 3*x^2 + 6*x*y + 3*y^2 - x^3 - 3*x^2*y - 2*y^3;"
656 "1 - 3*x - 3*y + 3*x^2 + 6*x*y + 3*y^2 - 2*x^3 - 3*x*y^2 - y^3;"
658 "-2/3 + 3/2*x + 2*y - x^2 - 3*x*y - 2*y^2 + 1/6*x^3 + x^2*y + 2*x*y^2;"
660 "-2/3 + 3/2*x + 2*y - x^2 - 3*x*y - 2*y^2 + x^3 + 3/2*x*y^2 + 2/3*y^3;"
661 "1/2*x*y^2 - 2/3*y^3;"
662 "-2/3 + 2*x + 3/2*y - 2*x^2 - 3*x*y - y^2 + 2/3*x^3 + 3/2*x^2*y + y^3;"
663 "-2/3*x^3 + 1/2*x^2*y;"
664 "-2/3 + 2*x + 3/2*y - 2*x^2 - 3*x*y - y^2 + 2*x^2*y + x*y^2 + 1/6*y^3;"
666 "4/3 - 2*x - 4*y + 4*x*y + 4*y^2 + 2/3*x^3 - 4*x*y^2;"
668 "4/3 - 2*x - 4*y + 4*x*y + 4*y^2 - 2*x*y^2 - 4/3*y^3;"
669 "-2*x*y^2 + 4/3*y^3;"
670 "-2/3 + 2*x - 2*x^2 + 2/3*x^3;"
671 "2*x^2 - 4*x*y - 2/3*x^3 + 4*x*y^2;"
672 "-2/3 + 2*x - 4*x*y + 2*y^2 + 2*x*y^2 - 4/3*y^3;"
673 "-2*y^2 + 2*x*y^2 + 4/3*y^3;"
674 "4/3 - 4*x - 2*y + 4*x^2 + 4*x*y - 4/3*x^3 - 2*x^2*y;"
676 "4/3 - 4*x - 2*y + 4*x^2 + 4*x*y - 4*x^2*y + 2/3*y^3;"
678 "-2/3 + 2*y + 2*x^2 - 4*x*y - 4/3*x^3 + 2*x^2*y;"
679 "-2*x^2 + 4/3*x^3 + 2*x^2*y;"
680 "-2/3 + 2*y - 2*y^2 + 2/3*y^3;"
681 "-4*x*y + 2*y^2 + 4*x^2*y - 2/3*y^3;");
685 dim() = cr->structure()->dim();
686 is_polynomialcomp() =
true;
687 is_equivalent() =
false;
688 is_polynomial() =
false;
689 is_lagrange() =
false;
690 is_standard() =
false;
691 estimated_degree() = 5;
694 base()=std::vector<bgeot::polynomial_composite>
695 (16, bgeot::polynomial_composite(mp,
false));
701 base_node pt(0.0, 0.0);
702 if (i & 1) pt[0] = 1.0;
703 if (i & 2) pt[1] = 1.0;
717 (fem_param_list ¶ms,
718 std::vector<dal::pstatic_stored_object> &dependencies) {
719 GMM_ASSERT1(params.size() == 0,
"Bad number of parameters : "
720 << params.size() <<
" should be 0.");
721 pfem p = std::make_shared<quadc1p3__>();
722 dependencies.push_back(p->ref_convex(0));
723 dependencies.push_back(p->node_tab(0));
731 struct reduced_quadc1p3__ :
public fem<bgeot::polynomial_composite> {
732 const quadc1p3__ *HCT;
733 virtual void mat_trans(base_matrix &M,
const base_matrix &G,
736 mutable base_matrix P, Mhct;
737 reduced_quadc1p3__(
void);
740 void reduced_quadc1p3__::mat_trans(base_matrix &M,
const base_matrix &G,
742 HCT->mat_trans(Mhct, G, pgt);
744 P(13, 1)=HCT->true_normals[1][0]*0.5; P(15, 1)=HCT->true_normals[3][0]*0.5;
745 P(13, 2)=HCT->true_normals[1][1]*0.5; P(15, 2)=HCT->true_normals[3][1]*0.5;
747 P(12, 4)=HCT->true_normals[0][0]*0.5; P(15, 4)=HCT->true_normals[3][0]*0.5;
748 P(12, 5)=HCT->true_normals[0][1]*0.5; P(15, 5)=HCT->true_normals[3][1]*0.5;
750 P(13, 7)=HCT->true_normals[1][0]*0.5; P(14, 7)=HCT->true_normals[2][0]*0.5;
751 P(13, 8)=HCT->true_normals[1][1]*0.5; P(14, 8)=HCT->true_normals[2][1]*0.5;
753 P(12,10)=HCT->true_normals[0][0]*0.5; P(14,10)=HCT->true_normals[2][0]*0.5;
754 P(12,11)=HCT->true_normals[0][1]*0.5; P(14,11)=HCT->true_normals[2][1]*0.5;
756 gmm::mult(gmm::transposed(P), Mhct, M);
759 reduced_quadc1p3__::reduced_quadc1p3__(
void)
760 : P(16, 12), Mhct(16, 16) {
761 HCT =
dynamic_cast<const quadc1p3__ *
>
766 dim() = cr->structure()->dim();
767 is_polynomialcomp() =
true;
768 is_equivalent() =
false;
769 is_polynomial() =
false;
770 is_lagrange() =
false;
771 is_standard() =
false;
772 estimated_degree() = 5;
773 base() = HCT->base();
775 gmm::copy(gmm::identity_matrix(), P);
779 base_node pt(0.0, 0.0);
780 if (i & 1) pt[0] = 1.0;
781 if (i & 2) pt[1] = 1.0;
789 pfem reduced_quadc1p3_fem
790 (fem_param_list ¶ms,
791 std::vector<dal::pstatic_stored_object> &dependencies) {
792 GMM_ASSERT1(params.size() == 0,
"Bad number of parameters : "
793 << params.size() <<
" should be 0.");
794 pfem p = std::make_shared<reduced_quadc1p3__>();
795 dependencies.push_back(p->ref_convex(0));
796 dependencies.push_back(p->node_tab(0));
811 pfem hho_method(fem_param_list ¶ms,
812 std::vector<dal::pstatic_stored_object> &dependencies) {
813 GMM_ASSERT1(params.size() >= 2,
"Bad number of parameters : "
814 << params.size() <<
" should be at least 2.");
815 GMM_ASSERT1(params[0].type() == 1 && params[1].type() == 1,
816 "Bad type of parameters");
817 pfem pf = params[0].method();
819 size_type nbf = pf->ref_convex(0)->structure()->nb_faces();
820 GMM_ASSERT1(pf->is_polynomial(),
"Only for polynomial elements");
822 std::vector<pfem> pff(nbf);
823 if (params.size() == 2)
824 std::fill(pff.begin(), pff.end(), params[1].method());
826 GMM_ASSERT1(params.size() == nbf+1,
"Bad number of parameters : "
827 << params.size() <<
" a single method for all the faces or "
828 " a method for each face.");
830 GMM_ASSERT1(params[i+1].type() == 1,
"Bad type of parameters");
831 GMM_ASSERT1(params[i+1].method()->is_polynomial(),
832 "Only for polynomial elements");
833 pff[i] = params[i+1].method();
838 bgeot::pbasic_mesh pm;
839 bgeot::pmesh_precomposite pmp;
843 bgeot::basic_mesh m0(*pm);
846 ipts=m0.ind_points_of_face_of_convex(0,i);
848 = m0.structure_of_convex(0)->faces_structure()[i];
849 m0.add_convex(bgeot::default_trans_of_cvs(cvs), ipts.begin());
854 bgeot::mesh_precomposite mp; mp.initialise(m1);
856 mf.set_finite_element(0, pf);
858 mf.set_finite_element(i+1, pff[i]);
860 pfem p = composite_fe_method(m1, mf, pf->ref_convex(0),
true);
861 dependencies.push_back(p->ref_convex(0));
862 dependencies.push_back(p->node_tab(0));
868 const polynomial_composite_fem *phho
869 =
dynamic_cast<const polynomial_composite_fem*
>(hho_method.get());
872 pfem pf0 = phho->mf.fem_of_element(0);
873 pfem pf1 = phho->mf.fem_of_element(1);
874 if (pf1 && (pf1->dim()+1 == pf0->dim()))
875 return phho->mf.fem_of_element(0);