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());
 
   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));
 
  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);
 
  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);
 
  331     for (
unsigned i = 9; i < 12; ++i) {
 
  332       if (!(pgt->is_linear()))
 
  335       gmm::mult(gmm::transposed(K), cvr->normals()[i-9], n);
 
  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) {
 
  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;
 
  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();
 
  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);
 
  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);
 
  570     for (
unsigned i = 12; i < 16; ++i) {
 
  571       if (!(pgt->is_linear()))
 
  574       gmm::mult(gmm::transposed(K), cvr->normals()[i-12], n);
 
  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) {
 
  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;
 
  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();
 
  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);
 
Handle composite polynomials.
 
Describe a mesh (collection of convexes (elements) and points).
 
size_type add_triangle(size_type a, size_type b, size_type c)
Add a triangle to the mesh, given the point id of its vertices.
 
void clear()
Erase the mesh.
 
indexed array reference (given a container X, and a set of indexes I, this class provides a pseudo-co...
 
Integration methods (exact and approximated) on convexes.
 
Define the getfem::mesh_fem class.
 
void copy(const L1 &l1, L2 &l2)
*/
 
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
 
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
 
strongest_value_type< V1, V2 >::value_type vect_sp(const V1 &v1, const V2 &v2)
*/
 
void lu_inverse(const DenseMatrixLU &LU, const Pvector &pvector, const DenseMatrix &AInv_)
Given an LU factored matrix, build the inverse of the matrix.
 
pdof_description derivative_dof(dim_type d, dim_type r)
Description of a unique dof of derivative type.
 
pdof_description lagrange_dof(dim_type d)
Description of a unique dof of lagrange type (value at the node).
 
pdof_description normal_derivative_dof(dim_type d)
Description of a unique dof of normal derivative type (normal derivative at the node,...
 
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
 
const fem< bgeot::polynomial_composite > * ppolycompfem
Polynomial composite FEM.
 
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
 
pfem interior_fem_of_hho_method(pfem hho_method)
Specific function for a HHO method to obtain the method in the interior.
 
pfem_precomp fem_precomp(pfem pf, bgeot::pstored_point_tab pspt, dal::pstatic_stored_object dep)
Handles precomputations for FEM.
 
const fem< bgeot::base_poly > * ppolyfem
Classical polynomial FEM.
 
gmm::uint16_type short_type
used as the common short type integer in the library
 
base_poly read_base_poly(short_type n, std::istream &f)
read a base_poly on the stream ist.
 
pconvex_ref simplex_of_reference(dim_type nc, short_type K)
returns a simplex of reference of dimension nc and degree k
 
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
 
void structured_mesh_for_convex(pconvex_ref cvr, short_type k, pbasic_mesh &pm, pmesh_precomposite &pmp, bool force_simplexification)
This function returns a mesh in pm which contains a refinement of the convex cvr if force_simplexific...
 
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.