27   void fem_sum::init() {
 
   28     cvr = pfems[0]->ref_convex(cv);
 
   29     dim_ = cvr->structure()->dim();
 
   30     is_equiv = !smart_global_dof_linking_;
 
   31     real_element_defined = 
true;
 
   32     is_polycomp = is_pol = is_lag = is_standard_fem = 
false;
 
   37     nm << 
"FEM_SUM(" << pfems[0]->debug_name() << 
",";
 
   38     for (
size_type i = 1; i < pfems.size(); ++i)
 
   39       nm << pfems[i]->debug_name() << 
",";
 
   40     nm << 
" cv:" << cv << 
")";
 
   41     debug_name_ = nm.str();
 
   44     for (
size_type i = 0; i < pfems.size(); ++i) {
 
   45       GMM_ASSERT1(pfems[i]->target_dim() == 1, 
"Vectorial fems not supported");
 
   47       for (
size_type k = 0; k < pfems[i]->nb_dof(cv); ++k) {
 
   48         add_node(pfems[i]->dof_types()[k], pfems[i]->node_of_dof(cv,k));
 
   54   void fem_sum::mat_trans(base_matrix &M,
 
   62     std::vector<pdof_description> hermdof(dim());
 
   63     for (dim_type 
id = 0; 
id < dim(); ++id)
 
   67     base_vector val(1), val2(1);
 
   68     base_matrix grad(1, dim());
 
   71     for (
size_type ifem1 = 0, i=0; ifem1 < pfems.size(); ++ifem1) {
 
   72       pfem pf1 = pfems[ifem1];
 
   74       for (
size_type idof1 = 0; idof1 < pf1->nb_dof(cv); ++idof1, ++i) {
 
   75         if (pf1->dof_types()[idof1] == gdof) {
 
   76           base_vector coeff(pfems[ifem1]->nb_dof(cv));
 
   78           fem_interpolation_context fic(pgt, pf1, base_node(dim()), G, cv);
 
   79           for (
size_type ifem2 = 0, j=0; ifem2 < pfems.size(); ++ifem2) {
 
   80             pfem pf2 = pfems[ifem2];
 
   81             fem_interpolation_context fic2(pgt, pf2, base_node(dim()), G, cv);
 
   82             for (
size_type idof2 = 0; idof2 < pf2->nb_dof(cv); ++idof2, ++j) {
 
   86               base_vector coeff2(pfems[ifem2]->nb_dof(cv));
 
   90                 fic.set_xref(pf2->node_of_dof(cv, idof2));
 
   91                 fic2.set_xref(pf2->node_of_dof(cv, idof2));
 
   92                 if (dof_weak_compatibility(pdd, lagdof) == 0) {
 
   93                   pfems[ifem1]->interpolation(fic, coeff, val, 1);
 
   95                   pfems[ifem2]->interpolation(fic2, coeff2, val2, 1);
 
   97                   M(i, j) = -val[0]*val2[0];
 
  105                 else for (
size_type id = 0; 
id < dim(); ++id) {
 
  106                   if (dof_weak_compatibility(pdd, hermdof[
id]) == 0) {
 
  107                     pfems[ifem1]->interpolation_grad(fic, coeff, grad, 1);
 
  108                     M(i, j) = -grad(0, 
id);
 
  109                     cout << 
"dof " << idof2 << 
"compatible with hermite " 
  115                             "Sorry, smart_global_dof_linking not " 
  116                             "compatible with this kind of dof");
 
  130     for (
size_type i = 0; i < pfems.size(); ++i) {
 
  132       if (j >= nb) j -= pfems[i]->nb_dof(cv);
 
  133       else return pfems[i]->index_of_global_dof(cv, j);
 
  135     GMM_ASSERT1(
false, 
"incoherent global dof.");
 
  138   void fem_sum::base_value(
const base_node &,
 
  140   { GMM_ASSERT1(
false, 
"No base values, real only element."); }
 
  141   void fem_sum::grad_base_value(
const base_node &,
 
  143   { GMM_ASSERT1(
false, 
"No base values, real only element."); }
 
  144   void fem_sum::hess_base_value(
const base_node &,
 
  146   { GMM_ASSERT1(
false, 
"No base values, real only element."); }
 
  148   void fem_sum::real_base_value(
const fem_interpolation_context &c,
 
  151     bgeot::multi_index mi(2);
 
  152     mi[1] = target_dim(); mi[0] = 
short_type(nb_dof(0));
 
  154     base_tensor::iterator it = t.begin(), itf;
 
  156     fem_interpolation_context c0 = c;
 
  157     std::vector<base_tensor> val_e(pfems.size());
 
  158     for (
size_type k = 0; k < pfems.size(); ++k) {
 
  160         c0.set_pfp(
fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
 
  162       } 
else { c0.set_pf(pfems[k]); }
 
  163       c0.base_value(val_e[k]);
 
  166     for (dim_type q = 0; q < target_dim(); ++q) {
 
  167       for (
size_type k = 0; k < pfems.size(); ++k) {
 
  168         itf = val_e[k].begin() + q * pfems[k]->nb_dof(cv);
 
  169         for (
size_type i = 0; i <  pfems[k]->nb_dof(cv); ++i)
 
  173     assert(it == t.end());
 
  174     if (!is_equivalent() && withM) {
 
  176       t.mat_transp_reduction(tt, c.M(), 0);
 
  181   void fem_sum::real_grad_base_value(
const fem_interpolation_context &c,
 
  182                                      base_tensor &t, 
bool withM)
 const {
 
  183     bgeot::multi_index mi(3);
 
  184     mi[2] = 
short_type(c.N()); mi[1] = target_dim();
 
  187     base_tensor::iterator it = t.begin(), itf;
 
  189     fem_interpolation_context c0 = c;
 
  190     std::vector<base_tensor> grad_e(pfems.size());
 
  191     for (
size_type k = 0; k < pfems.size(); ++k) {
 
  193         c0.set_pfp(
fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
 
  195       } 
else { c0.set_pf(pfems[k]); }
 
  196       c0.grad_base_value(grad_e[k]);
 
  199     for (dim_type k = 0; k < c.N() ; ++k) {
 
  200       for (dim_type q = 0; q < target_dim(); ++q) {
 
  201         for (
size_type f = 0; f < pfems.size(); ++f) {
 
  202           itf = grad_e[f].begin()
 
  203             + (k * target_dim() + q) * pfems[f]->nb_dof(cv);
 
  204           for (
size_type i = 0; i < pfems[f]->nb_dof(cv); ++i)
 
  209     assert(it == t.end());
 
  210     if (!is_equivalent() && withM) {
 
  212       t.mat_transp_reduction(tt, c.M(), 0);
 
  216   void fem_sum::real_hess_base_value(
const fem_interpolation_context &c,
 
  217                                      base_tensor &t, 
bool withM)
 const {
 
  218     t.adjust_sizes(nb_dof(0), target_dim(), gmm::sqr(c.N()));
 
  219     base_tensor::iterator it = t.begin(), itf;
 
  221     fem_interpolation_context c0 = c;
 
  222     std::vector<base_tensor> hess_e(pfems.size());
 
  223     for (
size_type k = 0; k < pfems.size(); ++k) {
 
  225         c0.set_pfp(
fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
 
  227       } 
else { c0.set_pf(pfems[k]); }
 
  228       c0.hess_base_value(hess_e[k]);
 
  231     dim_type NNdim = dim_type(gmm::sqr(c.N())*target_dim());
 
  232     for (dim_type jkq = 0; jkq < NNdim ; ++jkq) {
 
  233       for (
size_type f = 0; f < pfems.size(); ++f) {
 
  234         itf = hess_e[f].begin() + (jkq * pfems[f]->nb_dof(cv));
 
  235         for (
size_type i = 0; i < pfems[f]->nb_dof(cv); ++i)
 
  239     assert(it == t.end());
 
  240     if (!is_equivalent() && withM) {
 
  242       t.mat_transp_reduction(tt, c.M(), 0);
 
  246   void mesh_fem_sum::clear_build_methods() {
 
  247     for (
size_type i = 0; i < build_methods.size(); ++i)
 
  249     build_methods.clear();
 
  251   void mesh_fem_sum::clear() {
 
  253     clear_build_methods();
 
  258   DAL_SIMPLE_KEY(special_mflsum_key, 
pfem);
 
  260   void mesh_fem_sum::adapt() {
 
  264     for (
const mesh_fem *pmf : mfs)
 
  265       GMM_ASSERT1(!(pmf->is_reduced()),
 
  266                   "Sorry fem_sum for reduced mesh_fem is not implemented");
 
  269       std::vector<pfem> pfems;
 
  270       bool is_cv_dep = 
false;
 
  271       for (
const mesh_fem *pmf : mfs) {
 
  272         if (pmf->convex_index().is_in(i)) {
 
  273           pfem pf = pmf->fem_of_element(i);
 
  276             if (pf->is_on_real_element())
 
  281       if (pfems.size() == 1) {
 
  284       else if (pfems.size() > 0) {
 
  285         if (situations.find(pfems) == situations.end() || is_cv_dep) {
 
  286           pfem pf = std::make_shared<fem_sum>(pfems, i,
 
  287                                               smart_global_dof_linking_);
 
  288           dal::pstatic_stored_object_key
 
  289             pk = std::make_shared<special_mflsum_key>(pf);
 
  291           build_methods.push_back(pf);
 
  292           situations[pfems] = pf;
 
  297     is_adapted = 
true; touch();
 
bool context_check() const
return true if update_from_context was called
 
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
 
void set_finite_element(size_type cv, pfem pf)
Set the finite element method of a convex.
 
const dal::bit_vector & convex_index() const
Get the set of convexes where a finite element has been assigned.
 
Implement a special mesh_fem with merges the FEMs of two (or more) mesh_fems.
 
void copy(const L1 &l1, L2 &l2)
*/
 
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 global_dof(dim_type d)
Description of a global dof, i.e.
 
dof_description * pdof_description
Type representing a pointer on a dof_description.
 
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
 
pfem_precomp fem_precomp(pfem pf, bgeot::pstored_point_tab pspt, dal::pstatic_stored_object dep)
Handles precomputations for FEM.
 
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
 
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
 
void del_stored_object(const pstatic_stored_object &o, bool ignore_unstored)
Delete an object and the object which depend on it.
 
GEneric Tool for Finite Element Methods.