29   THREAD_SAFE_STATIC fem_precomp_pool HHO_pfp_pool;
 
   39   class _HHO_reconstructed_gradient
 
   40     : 
public virtual_elementary_transformation {
 
   44     virtual void give_transformation(
const mesh_fem &mf1, 
const mesh_fem &mf2,
 
   56       pfem pf1 = mf1.fem_of_element(cv);
 
   57       pfem pf2 = mf2.fem_of_element(cv);
 
   60       size_type degree = std::max(pf1->estimated_degree(),
 
   61                                   pf2->estimated_degree());
 
   63       papprox_integration pim
 
   67       bgeot::vectors_to_base_matrix(G, mf1.linked_mesh().points_of_convex(cv));
 
   69       bgeot::pgeotrans_precomp pgp
 
   70         = HHO_pgp_pool(pgt, pim->pintegration_points());
 
   71       pfem_precomp pfp1 = HHO_pfp_pool(pf1, pim->pintegration_points());
 
   72       pfem_precomp pfp2 = HHO_pfp_pool(pf2, pim->pintegration_points());
 
   73       pfem_precomp pfpi = HHO_pfp_pool(pfi, pim->pintegration_points());
 
   75       fem_interpolation_context ctx1(pgp, pfp1, 0, G, cv);
 
   76       fem_interpolation_context ctx2(pgp, pfp2, 0, G, cv);
 
   77       fem_interpolation_context ctxi(pgp, pfpi, 0, G, cv);
 
   79       size_type Q = mf1.get_qdim(), N = mf1.linked_mesh().dim();
 
   82       size_type ndof1 = pf1->nb_dof(cv) * qmult1;
 
   83       size_type qmult2 =  Q*N / pf2->target_dim();
 
   84       size_type ndof2 = pf2->nb_dof(cv) * qmult2;
 
   86       size_type ndofi = pfi->nb_dof(cv) * qmulti;
 
   88       base_tensor t1, t2, ti, tv1;
 
   89       base_matrix tv2, tv1p, tvi;
 
   90       base_matrix M1(ndof2, ndof1), M2(ndof2, ndof2), M2inv(ndof2, ndof2);
 
   91       base_matrix aux2(ndof2, ndof2);
 
   94       for (
size_type ipt = 0; ipt < pim->nb_points_on_convex(); ++ipt) {
 
   95         ctx1.set_ii(ipt); ctx2.set_ii(ipt);
 
   96         scalar_type coeff = pim->coeff(ipt) * ctx1.J();
 
   98         ctx1.grad_base_value(t1);
 
   99         vectorize_grad_base_tensor(t1, tv1, ndof1, pf1->target_dim(), Q);
 
  102         vectorize_base_tensor(t2, tv2, ndof2, pf2->target_dim(), Q*N);
 
  104         gmm::mult(tv2, gmm::transposed(tv2), aux2);
 
  105         gmm::add(gmm::scaled(aux2, coeff), M2);
 
  110               M1(j, i) += coeff * tv1.as_vector()[i+k*ndof1] * tv2(j, k);
 
  114       for (
short_type ifc = 0; ifc < pgt->structure()->nb_faces(); ++ifc) {
 
  115         ctx1.set_face_num(ifc); ctx2.set_face_num(ifc); ctxi.set_face_num(ifc);
 
  116         size_type first_ind = pim->ind_first_point_on_face(ifc);
 
  117         for (
size_type ipt = 0; ipt < pim->nb_points_on_face(ifc); ++ipt) {
 
  118           ctx1.set_ii(first_ind+ipt);
 
  119           ctx2.set_ii(first_ind+ipt);
 
  120           ctxi.set_ii(first_ind+ipt);
 
  121           scalar_type coeff = pim->coeff(first_ind+ipt) * ctx1.J();
 
  122           gmm::mult(ctx1.B(), pgt->normals()[ifc], un);
 
  125           vectorize_base_tensor(t2, tv2, ndof2, pf2->target_dim(), Q*N);
 
  128           vectorize_base_tensor(t1, tv1p, ndof1, pf1->target_dim(), Q);
 
  131           vectorize_base_tensor(ti, tvi, ndofi, pfi->target_dim(), Q);
 
  136                 scalar_type b(0), a = coeff *
 
  137                   (tv1p(i, k1) - (i < ndofi ? tvi(i, k1) : 0.));
 
  139                   b += a * tv2(j, k1 + k2*Q) * un[k2];
 
  145       if (pf2->target_dim() == 1) {
 
  146         gmm::sub_slice I(0, ndof2/(N*Q), N*Q);
 
  149           gmm::sub_slice I2(i, ndof2/(N*Q), N*Q);
 
  150           gmm::copy(gmm::sub_matrix(M2, I, I), gmm::sub_matrix(M2inv, I2, I2));
 
  155       gmm::clean(M, gmm::vect_norminf(M.as_vector()) * 1E-13);
 
  160     pelementary_transformation
 
  161       p = std::make_shared<_HHO_reconstructed_gradient>();
 
  166   class _HHO_reconstructed_sym_gradient
 
  167     : 
public virtual_elementary_transformation {
 
  171     virtual void give_transformation(
const mesh_fem &mf1, 
const mesh_fem &mf2,
 
  184       pfem pf1 = mf1.fem_of_element(cv);
 
  185       pfem pf2 = mf2.fem_of_element(cv);
 
  188       size_type degree = std::max(pf1->estimated_degree(),
 
  189                                   pf2->estimated_degree());
 
  191       papprox_integration pim
 
  195       bgeot::vectors_to_base_matrix(G, mf1.linked_mesh().points_of_convex(cv));
 
  197       bgeot::pgeotrans_precomp pgp
 
  198         = HHO_pgp_pool(pgt, pim->pintegration_points());
 
  199       pfem_precomp pfp1 = HHO_pfp_pool(pf1, pim->pintegration_points());
 
  200       pfem_precomp pfp2 = HHO_pfp_pool(pf2, pim->pintegration_points());
 
  201       pfem_precomp pfpi = HHO_pfp_pool(pfi, pim->pintegration_points());
 
  203       fem_interpolation_context ctx1(pgp, pfp1, 0, G, cv);
 
  204       fem_interpolation_context ctx2(pgp, pfp2, 0, G, cv);
 
  205       fem_interpolation_context ctxi(pgp, pfpi, 0, G, cv);
 
  207       size_type Q = mf1.get_qdim(), N = mf1.linked_mesh().dim();
 
  208       GMM_ASSERT1(Q == N, 
"This transformation works only for vector fields " 
  209                   "having the same dimension as the domain");
 
  211       size_type qmult1 =  N / pf1->target_dim();
 
  212       size_type ndof1 = pf1->nb_dof(cv) * qmult1;
 
  213       size_type qmult2 =  N*N / pf2->target_dim();
 
  214       size_type ndof2 = pf2->nb_dof(cv) * qmult2;
 
  215       size_type qmulti =  N / pfi->target_dim();
 
  216       size_type ndofi = pfi->nb_dof(cv) * qmulti;
 
  219       base_tensor t1, t2, ti, tv1;
 
  220       base_matrix tv2, tv1p, tvi;
 
  221       base_matrix M1(ndof2, ndof1), M2(ndof2, ndof2), M2inv(ndof2, ndof2);
 
  222       base_matrix aux2(ndof2, ndof2);
 
  226       for (
size_type ipt = 0; ipt < pim->nb_points_on_convex(); ++ipt) {
 
  227         ctx1.set_ii(ipt); ctx2.set_ii(ipt);
 
  228         scalar_type coeff = pim->coeff(ipt) * ctx1.J();
 
  230         ctx1.grad_base_value(t1);
 
  231         vectorize_grad_base_tensor(t1, tv1, ndof1, pf1->target_dim(), N);
 
  234         vectorize_base_tensor(t2, tv2, ndof2, pf2->target_dim(), N*N);
 
  236         gmm::mult(tv2, gmm::transposed(tv2), aux2);
 
  237         gmm::add(gmm::scaled(aux2, coeff), M2);
 
  243                 M1(j, i) += coeff * tv1.as_vector()[i+(k1+k2*N)*ndof1]
 
  244                   * 0.5 * (tv2(j, k1+k2*N) + tv2(j, k2+k1*N));
 
  248       for (
short_type ifc = 0; ifc < pgt->structure()->nb_faces(); ++ifc) {
 
  249         ctx1.set_face_num(ifc); ctx2.set_face_num(ifc); ctxi.set_face_num(ifc);
 
  250         size_type first_ind = pim->ind_first_point_on_face(ifc);
 
  251         for (
size_type ipt = 0; ipt < pim->nb_points_on_face(ifc); ++ipt) {
 
  252           ctx1.set_ii(first_ind+ipt);
 
  253           ctx2.set_ii(first_ind+ipt);
 
  254           ctxi.set_ii(first_ind+ipt);
 
  255           scalar_type coeff = pim->coeff(first_ind+ipt) * ctx1.J();
 
  256           gmm::mult(ctx1.B(), pgt->normals()[ifc], un);
 
  259           vectorize_base_tensor(t2, tv2, ndof2, pf2->target_dim(), N*N);
 
  262           vectorize_base_tensor(t1, tv1p, ndof1, pf1->target_dim(), N);
 
  265           vectorize_base_tensor(ti, tvi, ndofi, pfi->target_dim(), N);
 
  270                 scalar_type b(0), a = coeff *
 
  271                   (tv1p(i, k1) - (i < ndofi ? tvi(i, k1) : 0.));
 
  273                   b += a*0.5*(tv2(j, k1 + k2*N) + tv2(j, k2 + k1*N)) * un[k2];
 
  280       if (pf2->target_dim() == 1) {
 
  281         gmm::sub_slice I(0, ndof2/(N*Q), N*Q);
 
  284           gmm::sub_slice I2(i, ndof2/(N*Q), N*Q);
 
  285           gmm::copy(gmm::sub_matrix(M2, I, I), gmm::sub_matrix(M2inv, I2, I2));
 
  291       gmm::clean(M, gmm::vect_norminf(M.as_vector()) * 1E-13);
 
  296     pelementary_transformation
 
  297       p = std::make_shared<_HHO_reconstructed_sym_gradient>();
 
  303   class _HHO_reconstructed_value
 
  304     : 
public virtual_elementary_transformation {
 
  308     virtual void give_transformation(
const mesh_fem &mf1, 
const mesh_fem &mf2,
 
  322       pfem pf1 = mf1.fem_of_element(cv);
 
  323       pfem pf2 = mf2.fem_of_element(cv);
 
  326       size_type degree = std::max(pf1->estimated_degree(),
 
  327                                   pf2->estimated_degree());
 
  329       papprox_integration pim
 
  333       bgeot::vectors_to_base_matrix(G, mf1.linked_mesh().points_of_convex(cv));
 
  335       bgeot::pgeotrans_precomp pgp
 
  336         = HHO_pgp_pool(pgt, pim->pintegration_points());
 
  337       pfem_precomp pfp1 = HHO_pfp_pool(pf1, pim->pintegration_points());
 
  338       pfem_precomp pfp2 = HHO_pfp_pool(pf2, pim->pintegration_points());
 
  339       pfem_precomp pfpi = HHO_pfp_pool(pfi, pim->pintegration_points());
 
  341       fem_interpolation_context ctx1(pgp, pfp1, 0, G, cv);
 
  342       fem_interpolation_context ctx2(pgp, pfp2, 0, G, cv);
 
  343       fem_interpolation_context ctxi(pgp, pfpi, 0, G, cv);
 
  345       size_type Q = mf1.get_qdim(), N = mf1.linked_mesh().dim();
 
  347       size_type qmult1 =  Q / pf1->target_dim();
 
  348       size_type ndof1 = pf1->nb_dof(cv) * qmult1;
 
  349       size_type qmult2 =  Q / pf2->target_dim();
 
  350       size_type ndof2 = pf2->nb_dof(cv) * qmult2;
 
  351       size_type qmulti =  Q / pfi->target_dim();
 
  352       size_type ndofi = pfi->nb_dof(cv) * qmulti;
 
  355       base_tensor t1, t2, ti, tv1, tv2, t1p, t2p;
 
  356       base_matrix tv1p, tv2p, tvi;
 
  357       base_matrix M1(ndof2, ndof1), M2(ndof2, ndof2), M2inv(ndof2, ndof2);
 
  358       base_matrix M3(Q, ndof1), M4(Q, ndof2);
 
  359       base_matrix aux1(ndof2, ndof1), aux2(ndof2, ndof2);
 
  365       for (
size_type ipt = 0; ipt < pim->nb_points_on_convex(); ++ipt) {
 
  366         ctx1.set_ii(ipt); ctx2.set_ii(ipt);
 
  367         scalar_type coeff = pim->coeff(ipt) * ctx1.J();
 
  370         ctx1.grad_base_value(t1);
 
  371         vectorize_grad_base_tensor(t1, tv1, ndof1, pf1->target_dim(), Q);
 
  373         ctx1.base_value(t1p);
 
  374         vectorize_base_tensor(t1p, tv1p, ndof1, pf1->target_dim(), Q);
 
  376         ctx2.grad_base_value(t2);
 
  377         vectorize_grad_base_tensor(t2, tv2, ndof2, pf2->target_dim(), Q);
 
  379         ctx2.base_value(t2p);
 
  380         vectorize_base_tensor(t2p, tv2p, ndof2, pf2->target_dim(), Q);
 
  385               M2(j, i) += coeff * tv2.as_vector()[i+k*ndof2]
 
  386                                 * tv2.as_vector()[j+k*ndof2];
 
  390             M4(k,  i) += coeff * tv2p(i, k);
 
  395               M1(j, i) += coeff * tv1.as_vector()[i+k*ndof1]
 
  396                                 * tv2.as_vector()[j+k*ndof2];
 
  400             M3(k,  i) += coeff * tv1p(i, k);
 
  405       for (
short_type ifc = 0; ifc < pgt->structure()->nb_faces(); ++ifc) {
 
  406         ctx1.set_face_num(ifc); ctx2.set_face_num(ifc); ctxi.set_face_num(ifc);
 
  407         size_type first_ind = pim->ind_first_point_on_face(ifc);
 
  408         for (
size_type ipt = 0; ipt < pim->nb_points_on_face(ifc); ++ipt) {
 
  409           ctx1.set_ii(first_ind+ipt);
 
  410           ctx2.set_ii(first_ind+ipt);
 
  411           ctxi.set_ii(first_ind+ipt);
 
  412           scalar_type coeff = pim->coeff(first_ind+ipt) * ctx1.J();
 
  413           gmm::mult(ctx1.B(), pgt->normals()[ifc], un);
 
  415           ctx2.grad_base_value(t2);
 
  416           vectorize_grad_base_tensor(t2, tv2, ndof2, pf2->target_dim(), Q);
 
  419           vectorize_base_tensor(t1, tv1p, ndof1, pf1->target_dim(), Q);
 
  422           vectorize_base_tensor(ti, tvi, ndofi, pfi->target_dim(), Q);
 
  427                 scalar_type b(0), a = coeff *
 
  428                   (tv1p(i, k1) - (i < ndofi ? tvi(i, k1) : 0.));
 
  430                   b += a * tv2.as_vector()[j+(k1+k2*Q)*ndof2] * un[k2];
 
  438       scalar_type coeff_p = pow(area, -1. - 2./scalar_type(N));
 
  439       gmm::mult(gmm::transposed(M4), M4, aux2);
 
  440       gmm::add (gmm::scaled(aux2, coeff_p), M2);
 
  441       gmm::mult(gmm::transposed(M4), M3, aux1);
 
  442       gmm::add (gmm::scaled(aux1, coeff_p), M1);
 
  444       if (pf2->target_dim() == 1 && Q > 1) {
 
  445         gmm::sub_slice I(0, ndof2/Q, Q);
 
  448           gmm::sub_slice I2(i, ndof2/Q, Q);
 
  449           gmm::copy(gmm::sub_matrix(M2, I, I), gmm::sub_matrix(M2inv, I2, I2));
 
  455       gmm::clean(M, gmm::vect_norminf(M.as_vector()) * 1E-13);
 
  460     pelementary_transformation
 
  461       p = std::make_shared<_HHO_reconstructed_value>();
 
  466   class _HHO_reconstructed_sym_value
 
  467     : 
public virtual_elementary_transformation {
 
  471     virtual void give_transformation(
const mesh_fem &mf1, 
const mesh_fem &mf2,
 
  486       pfem pf1 = mf1.fem_of_element(cv);
 
  487       pfem pf2 = mf2.fem_of_element(cv);
 
  490       size_type degree = std::max(pf1->estimated_degree(),
 
  491                                   pf2->estimated_degree());
 
  493       papprox_integration pim
 
  497       bgeot::vectors_to_base_matrix(G, mf1.linked_mesh().points_of_convex(cv));
 
  499       bgeot::pgeotrans_precomp pgp
 
  500         = HHO_pgp_pool(pgt, pim->pintegration_points());
 
  501       pfem_precomp pfp1 = HHO_pfp_pool(pf1, pim->pintegration_points());
 
  502       pfem_precomp pfp2 = HHO_pfp_pool(pf2, pim->pintegration_points());
 
  503       pfem_precomp pfpi = HHO_pfp_pool(pfi, pim->pintegration_points());
 
  505       fem_interpolation_context ctx1(pgp, pfp1, 0, G, cv);
 
  506       fem_interpolation_context ctx2(pgp, pfp2, 0, G, cv);
 
  507       fem_interpolation_context ctxi(pgp, pfpi, 0, G, cv);
 
  509       size_type Q = mf1.get_qdim(), N = mf1.linked_mesh().dim();
 
  510       GMM_ASSERT1(Q == N, 
"This transformation works only for vector fields " 
  511                   "having the same dimension as the domain");
 
  513       size_type qmult1 =  N / pf1->target_dim();
 
  514       size_type ndof1 = pf1->nb_dof(cv) * qmult1;
 
  515       size_type qmult2 =  N / pf2->target_dim();
 
  516       size_type ndof2 = pf2->nb_dof(cv) * qmult2;
 
  517       size_type qmulti =  N / pfi->target_dim();
 
  518       size_type ndofi = pfi->nb_dof(cv) * qmulti;
 
  521       base_tensor t1, t2, ti, tv1, tv2, t1p, t2p;
 
  522       base_matrix tv1p, tv2p, tvi;
 
  523       base_matrix M1(ndof2, ndof1), M2(ndof2, ndof2), M2inv(ndof2, ndof2);;
 
  524       base_matrix M3(N, ndof1), M4(N, ndof2);
 
  525       base_matrix M5(N*N, ndof1), M6(N*N, ndof2);
 
  526       base_matrix aux1(ndof2, ndof1), aux2(ndof2, ndof2);
 
  533       for (
size_type ipt = 0; ipt < pim->nb_points_on_convex(); ++ipt) {
 
  534         ctx1.set_ii(ipt); ctx2.set_ii(ipt);
 
  535         scalar_type coeff = pim->coeff(ipt) * ctx1.J();
 
  538         ctx1.grad_base_value(t1);
 
  539         vectorize_grad_base_tensor(t1, tv1, ndof1, pf1->target_dim(), N);
 
  541         ctx1.base_value(t1p);
 
  542         vectorize_base_tensor(t1p, tv1p, ndof1, pf1->target_dim(), N);
 
  544         ctx2.grad_base_value(t2);
 
  545         vectorize_grad_base_tensor(t2, tv2, ndof2, pf2->target_dim(), N);
 
  547         ctx2.base_value(t2p);
 
  548         vectorize_base_tensor(t2p, tv2p, ndof2, pf2->target_dim(), N);
 
  554                 M2(j, i) += coeff * tv2.as_vector()[i+(k1+k2*N)*ndof2]
 
  555                   * 0.5 * (tv2.as_vector()[j+(k1+k2*N)*ndof2] +
 
  556                            tv2.as_vector()[j+(k2+k1*N)*ndof2]);
 
  560             M4(k,  i) += coeff * tv2p(i, k);
 
  565               M6(k1+k2*N, i) += 0.5*coeff*(tv2.as_vector()[i+(k1+k2*N)*ndof2] -
 
  566                                            tv2.as_vector()[i+(k2+k1*N)*ndof2]);
 
  572                 M1(j, i) += coeff * tv1.as_vector()[i+(k1+k2*N)*ndof1]
 
  573                   * 0.5 * (tv2.as_vector()[j+(k1+k2*N)*ndof2] +
 
  574                            tv2.as_vector()[j+(k2+k1*N)*ndof2]);
 
  578             M3(k,  i) += coeff * tv1p(i, k);
 
  584       for (
short_type ifc = 0; ifc < pgt->structure()->nb_faces(); ++ifc) {
 
  585         ctx1.set_face_num(ifc); ctx2.set_face_num(ifc); ctxi.set_face_num(ifc);
 
  586         size_type first_ind = pim->ind_first_point_on_face(ifc);
 
  587         for (
size_type ipt = 0; ipt < pim->nb_points_on_face(ifc); ++ipt) {
 
  588           ctx1.set_ii(first_ind+ipt);
 
  589           ctx2.set_ii(first_ind+ipt);
 
  590           ctxi.set_ii(first_ind+ipt);
 
  591           scalar_type coeff = pim->coeff(first_ind+ipt) * ctx1.J();
 
  592           gmm::mult(ctx1.B(), pgt->normals()[ifc], un);
 
  594           ctx2.grad_base_value(t2);
 
  595           vectorize_grad_base_tensor(t2, tv2, ndof2, pf2->target_dim(), N);
 
  598           vectorize_base_tensor(t1, tv1p, ndof1, pf1->target_dim(), N);
 
  601           vectorize_base_tensor(ti, tvi, ndofi, pfi->target_dim(), N);
 
  606                 scalar_type b(0), a = coeff *
 
  607                   (tv1p(i, k1) - (i < ndofi ? tvi(i, k1) : 0.));
 
  609                   b += a * 0.5 * (tv2.as_vector()[j+(k1+k2*N)*ndof2] +
 
  610                                   tv2.as_vector()[j+(k2+k1*N)*ndof2]) * un[k2];
 
  617                 M5(k1+k2*N, i) += 0.5 * coeff * (tv1p(i, k1) * un[k2] -
 
  618                                                  tv1p(i, k2) * un[k1]);
 
  623       scalar_type coeff_p1 = pow(area, -1. - 2./scalar_type(N));
 
  624       scalar_type coeff_p2 = pow(area, -1. - 1./scalar_type(N));
 
  625       gmm::mult(gmm::transposed(M4), M4, aux2);
 
  626       gmm::add (gmm::scaled(aux2, coeff_p1), M2);
 
  627       gmm::mult(gmm::transposed(M6), M6, aux2);
 
  628       gmm::add (gmm::scaled(aux2, coeff_p2), M2);
 
  629       gmm::mult(gmm::transposed(M4), M3, aux1);
 
  630       gmm::add (gmm::scaled(aux1, coeff_p1), M1);
 
  631       gmm::mult(gmm::transposed(M6), M5, aux1);
 
  632       gmm::add (gmm::scaled(aux1, coeff_p2), M1);
 
  637       gmm::clean(M, gmm::vect_norminf(M.as_vector()) * 1E-13);
 
  642     pelementary_transformation
 
  643       p = std::make_shared<_HHO_reconstructed_sym_value>();
 
  649 class _HHO_stabilization
 
  650     : 
public virtual_elementary_transformation {
 
  654     virtual void give_transformation(
const mesh_fem &mf1, 
const mesh_fem &mf2,
 
  676       GMM_ASSERT1(&mf1 == &mf2, 
"The HHO stabilization transformation is " 
  677                   "only defined on the HHO space to itself");
 
  680       pfem pf1 = mf1.fem_of_element(cv);
 
  687       papprox_integration pim
 
  691       bgeot::vectors_to_base_matrix(G, mf1.linked_mesh().points_of_convex(cv));
 
  693       bgeot::pgeotrans_precomp pgp
 
  694         = HHO_pgp_pool(pgt, pim->pintegration_points());
 
  695       pfem_precomp pfp1 = HHO_pfp_pool(pf1, pim->pintegration_points());
 
  696       pfem_precomp pfp2 = HHO_pfp_pool(pf2, pim->pintegration_points());
 
  697       pfem_precomp pfpi = HHO_pfp_pool(pfi, pim->pintegration_points());
 
  699       fem_interpolation_context ctx1(pgp, pfp1, 0, G, cv);
 
  700       fem_interpolation_context ctx2(pgp, pfp2, 0, G, cv);
 
  701       fem_interpolation_context ctxi(pgp, pfpi, 0, G, cv);
 
  703       size_type Q = mf1.get_qdim(), N = mf1.linked_mesh().dim();
 
  705       size_type qmult1 =  Q / pf1->target_dim();
 
  706       size_type ndof1 = pf1->nb_dof(cv) * qmult1;
 
  707       size_type qmult2 =  Q / pf2->target_dim();
 
  708       size_type ndof2 = pf2->nb_dof(cv) * qmult2;
 
  709       size_type qmulti =  Q / pfi->target_dim();
 
  710       size_type ndofi = pfi->nb_dof(cv) * qmulti;
 
  713       base_tensor t1, t2, ti, tv1, tv2, t1p, t2p;
 
  714       base_matrix tv1p, tv2p, tvi;
 
  715       base_matrix M1(ndof2, ndof1), M2(ndof2, ndof2), M2inv(ndof2, ndof2);
 
  716       base_matrix M3(Q, ndof1), M4(Q, ndof2);
 
  717       base_matrix aux1(ndof2, ndof1), aux2(ndof2, ndof2);
 
  718       base_matrix M7(ndof1, ndof1), M7inv(ndof1, ndof1), M8(ndof1, ndof2);
 
  719       base_matrix M9(ndof1, ndof1), MD(ndof2, ndof1);
 
  725       for (
size_type ipt = 0; ipt < pim->nb_points_on_convex(); ++ipt) {
 
  726         ctx1.set_ii(ipt); ctx2.set_ii(ipt);
 
  727         scalar_type coeff = pim->coeff(ipt) * ctx1.J();
 
  730         ctx1.grad_base_value(t1);
 
  731         vectorize_grad_base_tensor(t1, tv1, ndof1, pf1->target_dim(), Q);
 
  733         ctx1.base_value(t1p);
 
  734         vectorize_base_tensor(t1p, tv1p, ndof1, pf1->target_dim(), Q);
 
  736         ctx2.grad_base_value(t2);
 
  737         vectorize_grad_base_tensor(t2, tv2, ndof2, pf2->target_dim(), Q);
 
  739         ctx2.base_value(t2p);
 
  740         vectorize_base_tensor(t2p, tv2p, ndof2, pf2->target_dim(), Q);
 
  745               M2(j, i) += coeff * tv2.as_vector()[i+k*ndof2]
 
  746                                 * tv2.as_vector()[j+k*ndof2];
 
  750             M4(k,  i) += coeff * tv2p(i, k);
 
  755               M1(j, i) += coeff * tv1.as_vector()[i+k*ndof1]
 
  756                                 * tv2.as_vector()[j+k*ndof2];
 
  760             M3(k,  i) += coeff * tv1p(i, k);
 
  765               M7(i, j) += coeff * tv1p(i, k) * tv1p(j, k);
 
  770               M8(i, j) += coeff * tv1p(i, k) * tv2p(j, k);
 
  775       for (
short_type ifc = 0; ifc < pgt->structure()->nb_faces(); ++ifc) {
 
  776         ctx1.set_face_num(ifc); ctx2.set_face_num(ifc); ctxi.set_face_num(ifc);
 
  777         size_type first_ind = pim->ind_first_point_on_face(ifc);
 
  778         for (
size_type ipt = 0; ipt < pim->nb_points_on_face(ifc); ++ipt) {
 
  779           ctx1.set_ii(first_ind+ipt);
 
  780           ctx2.set_ii(first_ind+ipt);
 
  781           ctxi.set_ii(first_ind+ipt);
 
  782           scalar_type coeff = pim->coeff(first_ind+ipt) * ctx1.J();
 
  783           gmm::mult(ctx1.B(), pgt->normals()[ifc], un);
 
  786           ctx2.grad_base_value(t2);
 
  787           vectorize_grad_base_tensor(t2, tv2, ndof2, pf2->target_dim(), Q);
 
  789           ctx2.base_value(t2p);
 
  790           vectorize_base_tensor(t2p, tv2p, ndof2, pf2->target_dim(), Q);
 
  793           vectorize_base_tensor(t1, tv1p, ndof1, pf1->target_dim(), Q);
 
  796           vectorize_base_tensor(ti, tvi, ndofi, pfi->target_dim(), Q);
 
  802                 scalar_type b(0), a = coeff *
 
  803                   (tv1p(i, k1) - (i < ndofi ? tvi(i, k1) : 0.));
 
  805                   b += a * tv2.as_vector()[j+(k1 + k2*Q)*ndof2] * un[k2];
 
  812                 M7(i, j) += coeff * normun * tv1p(i,k) * tv1p(j, k);
 
  817                 M8(i, j) += coeff * normun * tv1p(i,k) * tv2p(j, k);
 
  822                 M9(i, j) += coeff * normun * tv1p(i,k) * tvi(j, k); 
 
  827       scalar_type coeff_p = pow(area, -1. - 2./scalar_type(N));
 
  828       gmm::mult(gmm::transposed(M4), M4, aux2);
 
  829       gmm::add (gmm::scaled(aux2, coeff_p), M2);
 
  830       gmm::mult(gmm::transposed(M4), M3, aux1);
 
  831       gmm::add (gmm::scaled(aux1, coeff_p), M1);
 
  833       if (pf2->target_dim() == 1 && Q > 1) {
 
  834         gmm::sub_slice I(0, ndof2/Q, Q);
 
  837           gmm::sub_slice I2(i, ndof2/Q, Q);
 
  838           gmm::copy(gmm::sub_matrix(M2, I, I), gmm::sub_matrix(M2inv, I2, I2));
 
  843       if (pf1->target_dim() == 1 && Q > 1) {
 
  844         gmm::sub_slice I(0, ndof1/Q, Q);
 
  847           gmm::sub_slice I2(i, ndof1/Q, Q);
 
  848           gmm::copy(gmm::sub_matrix(M7, I, I), gmm::sub_matrix(M7inv, I2, I2));
 
  854       gmm::clean(MD, gmm::vect_norminf(MD.as_vector()) * 1E-13);
 
  857       base_matrix MPB(ndof1, ndof1);
 
  860       gmm::add(gmm::scaled(MPB, scalar_type(-1)), M9);
 
  862       base_matrix MPC(ndof1, ndof1), MPD(ndof1, ndof1);
 
  866       gmm::add(gmm::scaled(MPD, scalar_type(-1)), M7);
 
  874     pelementary_transformation
 
  875       p = std::make_shared<_HHO_stabilization>();
 
  876     md.add_elementary_transformation(name, p);
 
  883   class _HHO_stabilization
 
  884     : 
public virtual_elementary_transformation {
 
  888     virtual void give_transformation(
const mesh_fem &mf1, 
const mesh_fem &mf2,
 
  911       pfem pf1 = mf1.fem_of_element(cv);
 
  916       pfem pf3 = mf2.fem_of_element(cv);
 
  920       papprox_integration pim
 
  924       bgeot::vectors_to_base_matrix(G, mf1.linked_mesh().points_of_convex(cv));
 
  926       bgeot::pgeotrans_precomp pgp
 
  927         = HHO_pgp_pool(pgt, pim->pintegration_points());
 
  928       pfem_precomp pfp1 = HHO_pfp_pool(pf1, pim->pintegration_points());
 
  929       pfem_precomp pfp2 = HHO_pfp_pool(pf2, pim->pintegration_points());
 
  930       pfem_precomp pfp3 = HHO_pfp_pool(pf3, pim->pintegration_points());
 
  931       pfem_precomp pfp1i = HHO_pfp_pool(pf1i, pim->pintegration_points());
 
  932       pfem_precomp pfp3i = HHO_pfp_pool(pf3i, pim->pintegration_points());
 
  934       fem_interpolation_context ctx1(pgp, pfp1, 0, G, cv);
 
  935       fem_interpolation_context ctx2(pgp, pfp2, 0, G, cv);
 
  936       fem_interpolation_context ctx3(pgp, pfp3, 0, G, cv);
 
  937       fem_interpolation_context ctx1i(pgp, pfp1i, 0, G, cv);
 
  938       fem_interpolation_context ctx3i(pgp, pfp3i, 0, G, cv);
 
  940       size_type Q = mf1.get_qdim(), N = mf1.linked_mesh().dim();
 
  942       size_type qmult1 =  Q / pf1->target_dim();
 
  943       size_type ndof1 = pf1->nb_dof(cv) * qmult1;
 
  944       size_type qmult2 =  Q / pf2->target_dim();
 
  945       size_type ndof2 = pf2->nb_dof(cv) * qmult2;
 
  946       size_type qmult3 =  Q / pf3->target_dim();
 
  947       size_type ndof3 = pf3->nb_dof(cv) * qmult3;
 
  948       size_type qmult1i =  Q / pf1i->target_dim();
 
  949       size_type ndof1i = pf1i->nb_dof(cv) * qmult1i;
 
  950       size_type qmult3i =  Q / pf3i->target_dim();
 
  951       size_type ndof3i = pf3i->nb_dof(cv) * qmult3i;
 
  954       base_tensor t1, t2, t3, t1i, t3i, tv1, tv2, t1p, t2p;
 
  955       base_matrix tv1p, tv2p, tv3p, tv1i, tv3i;
 
  956       base_matrix M1(ndof2, ndof1), M2(ndof2, ndof2), M2inv(ndof2, ndof2);
 
  957       base_matrix M3(Q, ndof1), M4(Q, ndof2);
 
  958       base_matrix aux1(ndof2, ndof1), aux2(ndof2, ndof2);
 
  959       base_matrix M7(ndof3, ndof3), M7inv(ndof3, ndof3), M8(ndof3, ndof2);
 
  960       base_matrix M9(ndof3, ndof1), M10(ndof3, ndof3), MD(ndof2, ndof1);
 
  966       for (
size_type ipt = 0; ipt < pim->nb_points_on_convex(); ++ipt) {
 
  967         ctx1.set_ii(ipt); ctx2.set_ii(ipt); ctx3.set_ii(ipt);
 
  968         scalar_type coeff = pim->coeff(ipt) * ctx1.J();
 
  971         ctx1.grad_base_value(t1);
 
  972         vectorize_grad_base_tensor(t1, tv1, ndof1, pf1->target_dim(), Q);
 
  974         ctx1.base_value(t1p);
 
  975         vectorize_base_tensor(t1p, tv1p, ndof1, pf1->target_dim(), Q);
 
  977         ctx2.grad_base_value(t2);
 
  978         vectorize_grad_base_tensor(t2, tv2, ndof2, pf2->target_dim(), Q);
 
  980         ctx2.base_value(t2p);
 
  981         vectorize_base_tensor(t2p, tv2p, ndof2, pf2->target_dim(), Q);
 
  984         vectorize_base_tensor(t3, tv3p, ndof3, pf3->target_dim(), Q);
 
  989               M2(j, i) += coeff * tv2.as_vector()[i+k*ndof2]
 
  990                                 * tv2.as_vector()[j+k*ndof2];
 
  994             M4(k,  i) += coeff * tv2p(i, k);
 
  999               M1(j, i) += coeff * tv1.as_vector()[i+k*ndof1]
 
 1000                                 * tv2.as_vector()[j+k*ndof2];
 
 1004             M3(k,  i) += coeff * tv1p(i, k);
 
 1009               M7(i, j) += coeff * tv3p(i, k) * tv3p(j, k);
 
 1014               M8(i, j) += coeff * tv3p(i, k) * tv2p(j, k);
 
 1019               M9(i, j) += coeff * tv3p(i, k) * tv1p(j, k);
 
 1023       for (
short_type ifc = 0; ifc < pgt->structure()->nb_faces(); ++ifc) {
 
 1024         ctx1.set_face_num(ifc); ctx2.set_face_num(ifc); ctx3.set_face_num(ifc);
 
 1025         ctx1i.set_face_num(ifc); ctx3i.set_face_num(ifc);
 
 1026         size_type first_ind = pim->ind_first_point_on_face(ifc);
 
 1027         for (
size_type ipt = 0; ipt < pim->nb_points_on_face(ifc); ++ipt) {
 
 1028           ctx1.set_ii(first_ind+ipt); ctx2.set_ii(first_ind+ipt);
 
 1029           ctx3.set_ii(first_ind+ipt); ctx1i.set_ii(first_ind+ipt);
 
 1030           ctx3i.set_ii(first_ind+ipt);
 
 1031           scalar_type coeff = pim->coeff(first_ind+ipt) * ctx1.J();
 
 1032           gmm::mult(ctx1.B(), pgt->normals()[ifc], un);
 
 1035           ctx2.grad_base_value(t2);
 
 1036           vectorize_grad_base_tensor(t2, tv2, ndof2, pf2->target_dim(), Q);
 
 1038           ctx2.base_value(t2p);
 
 1039           vectorize_base_tensor(t2p, tv2p, ndof2, pf2->target_dim(), Q);
 
 1041           ctx1.base_value(t1);
 
 1042           vectorize_base_tensor(t1, tv1p, ndof1, pf1->target_dim(), Q);
 
 1044           ctx1i.base_value(t1i);
 
 1045           vectorize_base_tensor(t1i, tv1i, ndof1i, pf1i->target_dim(), Q);
 
 1047           ctx3i.base_value(t3i);
 
 1048           vectorize_base_tensor(t3i, tv3i, ndof3i, pf3i->target_dim(), Q);
 
 1050           ctx3.base_value(t3);
 
 1051           vectorize_base_tensor(t3, tv3p, ndof3, pf3->target_dim(), Q);
 
 1057                 scalar_type b(0), a = coeff *
 
 1058                   (tv1p(i, k1) - (i < ndof1i ? tv1i(i, k1) : 0.));
 
 1060                   b += a * tv2.as_vector()[j+(k1 + k2*Q)*ndof2] * un[k2];
 
 1067                 M7(i, j) += coeff * normun * tv3p(i,k) * tv3p(j, k);
 
 1072                 M8(i, j) += coeff * normun * tv3p(i,k) * tv2p(j, k);
 
 1077                 M9(i, j) += coeff * normun * tv3p(i, k) * tv1p(j, k);
 
 1082                 M10(i, j) += coeff * normun * tv3p(i,k) * tv3i(j, k); 
 
 1087       scalar_type coeff_p = pow(area, -1. - 2./scalar_type(N));
 
 1088       gmm::mult(gmm::transposed(M4), M4, aux2);
 
 1089       gmm::add (gmm::scaled(aux2, coeff_p), M2);
 
 1090       gmm::mult(gmm::transposed(M4), M3, aux1);
 
 1091       gmm::add (gmm::scaled(aux1, coeff_p), M1);
 
 1093       if (pf2->target_dim() == 1 && Q > 1) {
 
 1094         gmm::sub_slice I(0, ndof2/Q, Q);
 
 1097           gmm::sub_slice I2(i, ndof2/Q, Q);
 
 1098           gmm::copy(gmm::sub_matrix(M2, I, I), gmm::sub_matrix(M2inv, I2, I2));
 
 1103       if (pf3->target_dim() == 1 && Q > 1) {
 
 1104         gmm::sub_slice I(0, ndof3/Q, Q);
 
 1107           gmm::sub_slice I2(i, ndof3/Q, Q);
 
 1108           gmm::copy(gmm::sub_matrix(M7, I, I), gmm::sub_matrix(M7inv, I2, I2));
 
 1114       gmm::clean(MD, gmm::vect_norminf(MD.as_vector()) * 1E-13);
 
 1117       base_matrix MPB(ndof3, ndof3);
 
 1120       gmm::add(gmm::scaled(MPB, scalar_type(-1)), M10);
 
 1122       base_matrix MPC(ndof3, ndof1);
 
 1123       gmm::mult(gmm::scaled(M8, scalar_type(-1)), MD, MPC);
 
 1132     pelementary_transformation
 
 1133       p = std::make_shared<_HHO_stabilization>();
 
 1139   class _HHO_symmetrized_stabilization
 
 1140     : 
public virtual_elementary_transformation {
 
 1144     virtual void give_transformation(
const mesh_fem &mf1, 
const mesh_fem &mf2,
 
 1168       pfem pf1 = mf1.fem_of_element(cv);
 
 1173       pfem pf3 = mf2.fem_of_element(cv);
 
 1177       papprox_integration pim
 
 1181       bgeot::vectors_to_base_matrix(G, mf1.linked_mesh().points_of_convex(cv));
 
 1183       bgeot::pgeotrans_precomp pgp
 
 1184         = HHO_pgp_pool(pgt, pim->pintegration_points());
 
 1185       pfem_precomp pfp1 = HHO_pfp_pool(pf1, pim->pintegration_points());
 
 1186       pfem_precomp pfp2 = HHO_pfp_pool(pf2, pim->pintegration_points());
 
 1187       pfem_precomp pfp3 = HHO_pfp_pool(pf3, pim->pintegration_points());
 
 1188       pfem_precomp pfp1i = HHO_pfp_pool(pf1i, pim->pintegration_points());
 
 1189       pfem_precomp pfp3i = HHO_pfp_pool(pf3i, pim->pintegration_points());
 
 1191       fem_interpolation_context ctx1(pgp, pfp1, 0, G, cv);
 
 1192       fem_interpolation_context ctx2(pgp, pfp2, 0, G, cv);
 
 1193       fem_interpolation_context ctx3(pgp, pfp3, 0, G, cv);
 
 1194       fem_interpolation_context ctx1i(pgp, pfp1i, 0, G, cv);
 
 1195       fem_interpolation_context ctx3i(pgp, pfp3i, 0, G, cv);
 
 1197       size_type Q = mf1.get_qdim(), N = mf1.linked_mesh().dim();
 
 1198       GMM_ASSERT1(Q == N, 
"This transformation works only for vector fields " 
 1199                   "having the same dimension as the domain");
 
 1201       size_type qmult1 =  N / pf1->target_dim();
 
 1202       size_type ndof1 = pf1->nb_dof(cv) * qmult1;
 
 1203       size_type qmult2 =  N / pf2->target_dim();
 
 1204       size_type ndof2 = pf2->nb_dof(cv) * qmult2;
 
 1205       size_type qmult3 =  Q / pf3->target_dim();
 
 1206       size_type ndof3 = pf3->nb_dof(cv) * qmult3;
 
 1207       size_type qmult1i =  Q / pf1i->target_dim();
 
 1208       size_type ndof1i = pf1i->nb_dof(cv) * qmult1i;
 
 1209       size_type qmult3i =  Q / pf3i->target_dim();
 
 1210       size_type ndof3i = pf3i->nb_dof(cv) * qmult3i;
 
 1213       base_tensor t1, t2, t3, t1i, t3i, tv1, tv2, t1p, t2p;
 
 1214       base_matrix tv1p, tv2p, tv3p, tv1i, tv3i;
 
 1215       base_matrix M1(ndof2, ndof1), M2(ndof2, ndof2), M2inv(ndof2, ndof2);
 
 1216       base_matrix M3(N, ndof1), M4(N, ndof2);
 
 1217       base_matrix aux1(ndof2, ndof1), aux2(ndof2, ndof2);
 
 1218       base_matrix M5(N*N, ndof1), M6(N*N, ndof2);
 
 1219       base_matrix M7(ndof3, ndof3), M7inv(ndof3, ndof3), M8(ndof3, ndof2);
 
 1220       base_matrix M9(ndof3, ndof1), M10(ndof3, ndof3), MD(ndof2, ndof1);
 
 1221       scalar_type area(0);
 
 1227       for (
size_type ipt = 0; ipt < pim->nb_points_on_convex(); ++ipt) {
 
 1228         ctx1.set_ii(ipt); ctx2.set_ii(ipt); ctx3.set_ii(ipt);
 
 1229         scalar_type coeff = pim->coeff(ipt) * ctx1.J();
 
 1232         ctx1.grad_base_value(t1);
 
 1233         vectorize_grad_base_tensor(t1, tv1, ndof1, pf1->target_dim(), Q);
 
 1235         ctx1.base_value(t1p);
 
 1236         vectorize_base_tensor(t1p, tv1p, ndof1, pf1->target_dim(), Q);
 
 1238         ctx2.grad_base_value(t2);
 
 1239         vectorize_grad_base_tensor(t2, tv2, ndof2, pf2->target_dim(), Q);
 
 1241         ctx2.base_value(t2p);
 
 1242         vectorize_base_tensor(t2p, tv2p, ndof2, pf2->target_dim(), Q);
 
 1244         ctx3.base_value(t3);
 
 1245         vectorize_base_tensor(t3, tv3p, ndof3, pf3->target_dim(), Q);
 
 1251                M2(j, i) += coeff * tv2.as_vector()[i+(k1+k2*N)*ndof2]
 
 1252                  * 0.5 * (tv2.as_vector()[j+(k1+k2*N)*ndof2] +
 
 1253                           tv2.as_vector()[j+(k2+k1*N)*ndof2]);
 
 1257             M4(k,  i) += coeff * tv2p(i, k);
 
 1262               M6(k1+k2*N, i) += 0.5*coeff*(tv2.as_vector()[i+(k1+k2*N)*ndof2] -
 
 1263                                            tv2.as_vector()[i+(k2+k1*N)*ndof2]);
 
 1269                 M1(j, i) += coeff * tv1.as_vector()[i+(k1+k2*N)*ndof1]
 
 1270                   * 0.5 * (tv2.as_vector()[j+(k1+k2*N)*ndof2] +
 
 1271                            tv2.as_vector()[j+(k2+k1*N)*ndof2]);
 
 1275             M3(k,  i) += coeff * tv1p(i, k);
 
 1280               M7(i, j) += coeff * tv3p(i,k) * tv3p(j, k);
 
 1285               M8(i, j) += coeff * tv3p(i,k) * tv2p(j, k);
 
 1290               M9(i, j) += coeff * tv3p(i, k) * tv1p(j, k);
 
 1295       for (
short_type ifc = 0; ifc < pgt->structure()->nb_faces(); ++ifc) {
 
 1296         ctx1.set_face_num(ifc); ctx2.set_face_num(ifc); ctx3.set_face_num(ifc);
 
 1297         ctx1i.set_face_num(ifc); ctx3i.set_face_num(ifc);
 
 1298         size_type first_ind = pim->ind_first_point_on_face(ifc);
 
 1299         for (
size_type ipt = 0; ipt < pim->nb_points_on_face(ifc); ++ipt) {
 
 1300           ctx1.set_ii(first_ind+ipt); ctx2.set_ii(first_ind+ipt);
 
 1301           ctx3.set_ii(first_ind+ipt); ctx1i.set_ii(first_ind+ipt);
 
 1302           ctx3i.set_ii(first_ind+ipt);
 
 1303           scalar_type coeff = pim->coeff(first_ind+ipt) * ctx1.J();
 
 1304           gmm::mult(ctx1.B(), pgt->normals()[ifc], un);
 
 1307           ctx2.grad_base_value(t2);
 
 1308           vectorize_grad_base_tensor(t2, tv2, ndof2, pf2->target_dim(), Q);
 
 1310           ctx2.base_value(t2p);
 
 1311           vectorize_base_tensor(t2p, tv2p, ndof2, pf2->target_dim(), Q);
 
 1313           ctx1.base_value(t1);
 
 1314           vectorize_base_tensor(t1, tv1p, ndof1, pf1->target_dim(), Q);
 
 1316           ctx1i.base_value(t1i);
 
 1317           vectorize_base_tensor(t1i, tv1i, ndof1i, pf1i->target_dim(), Q);
 
 1319           ctx3i.base_value(t3i);
 
 1320           vectorize_base_tensor(t3i, tv3i, ndof3i, pf3i->target_dim(), Q);
 
 1322           ctx3.base_value(t3);
 
 1323           vectorize_base_tensor(t3, tv3p, ndof3, pf3->target_dim(), Q);
 
 1328                 scalar_type b(0), a = coeff *
 
 1329                   (tv1p(i, k1) - (i < ndof1i ? tv1i(i, k1) : 0.));
 
 1331                   b += a * 0.5 * (tv2.as_vector()[j+(k1 + k2*N)*ndof2] +
 
 1332                                   tv2.as_vector()[j+(k2 + k1*N)*ndof2])* un[k2];
 
 1339                 M5(k1+k2*N, i) += 0.5 * coeff * (tv1p(i, k1) * un[k2] -
 
 1340                                                  tv1p(i, k2) * un[k1]);
 
 1345                 M7(i, j) += coeff * normun * tv3p(i,k) * tv3p(j, k);
 
 1350                 M8(i, j) += coeff * normun * tv3p(i,k) * tv2p(j, k);
 
 1355                 M9(i, j) += coeff * normun * tv3p(i, k) * tv1p(j, k);
 
 1360                 M10(i, j) += coeff * normun * tv3p(i,k) * tv3i(j, k);
 
 1365       scalar_type coeff_p1 = pow(area, -1. - 2./scalar_type(N));
 
 1366       scalar_type coeff_p2 = pow(area, -1. - 1./scalar_type(N));
 
 1367       gmm::mult(gmm::transposed(M4), M4, aux2);
 
 1368       gmm::add (gmm::scaled(aux2, coeff_p1), M2);
 
 1369       gmm::mult(gmm::transposed(M6), M6, aux2);
 
 1370       gmm::add (gmm::scaled(aux2, coeff_p2), M2);
 
 1371       gmm::mult(gmm::transposed(M4), M3, aux1);
 
 1372       gmm::add (gmm::scaled(aux1, coeff_p1), M1);
 
 1373       gmm::mult(gmm::transposed(M6), M5, aux1);
 
 1374       gmm::add (gmm::scaled(aux1, coeff_p2), M1);
 
 1378       if (pf3->target_dim() == 1 && Q > 1) {
 
 1379         gmm::sub_slice I(0, ndof3/Q, Q);
 
 1382           gmm::sub_slice I2(i, ndof3/Q, Q);
 
 1383           gmm::copy(gmm::sub_matrix(M7, I, I), gmm::sub_matrix(M7inv, I2, I2));
 
 1389       gmm::clean(MD, gmm::vect_norminf(MD.as_vector()) * 1E-13);
 
 1392       base_matrix MPB(ndof3, ndof3);
 
 1395       gmm::add(gmm::scaled(MPB, scalar_type(-1)), M10);
 
 1397       base_matrix MPC(ndof3, ndof1);
 
 1398       gmm::mult(gmm::scaled(M8, scalar_type(-1)), MD, MPC);
 
 1407     pelementary_transformation
 
 1408       p = std::make_shared<_HHO_symmetrized_stabilization>();
 
The object geotrans_precomp_pool Allow to allocate a certain number of geotrans_precomp and automatic...
 
`‘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.
 
Tools for Hybrid-High-Order methods.
 
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 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 classical_fem(bgeot::pgeometric_trans pgt, short_type k, bool complete=false)
Give a pointer on the structures describing the classical polynomial fem of degree k on a given conve...
 
pfem interior_fem_of_hho_method(pfem hho_method)
Specific function for a HHO method to obtain the method in the interior.
 
gmm::uint16_type short_type
used as the common short type integer in the library
 
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.
 
void add_HHO_symmetrized_stabilization(model &md, std::string name)
Add to the model the elementary transformation corresponding to the HHO stabilization operator using ...
 
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_HHO_reconstructed_value(model &md, std::string name)
Add to the model the elementary transformation corresponding to the reconstruction of the variable.
 
void add_HHO_reconstructed_symmetrized_value(model &md, std::string name)
Add to the model the elementary transformation corresponding to the reconstruction of the variable us...
 
void add_HHO_reconstructed_symmetrized_gradient(model &md, std::string name)
Add to the model the elementary transformation corresponding to the reconstruction of a symmetrized g...
 
void add_HHO_stabilization(model &md, std::string name)
Add to the model the elementary transformation corresponding to the HHO stabilization operator.
 
void add_HHO_reconstructed_gradient(model &md, std::string name)
Add to the model the elementary transformation corresponding to the reconstruction of a gradient for ...