31     for (dal::bv_visitor cv(fe_convex); !cv.finished(); ++cv) {
 
   33         if (v_num_update < linked_mesh_->convex_version_number(cv)) {
 
   34           if (auto_add_elt_pf != 0)
 
   37           else if (auto_add_elt_K != dim_type(-1)) {
 
   38             if (auto_add_elt_disc)
 
   41                   (cv, auto_add_elt_K, auto_add_elt_alpha,
 
   42                    auto_add_elt_complete);
 
   46                                                auto_add_elt_complete);
 
   55          !cv.finished(); ++cv) {
 
   56       if (!fe_convex.is_in(cv)
 
   58         if (auto_add_elt_pf != 0)
 
   61         else if (auto_add_elt_K != dim_type(-1)) {
 
   62           if (auto_add_elt_disc)
 
   65                 (cv, auto_add_elt_K, auto_add_elt_alpha, auto_add_elt_complete);
 
   69                                              auto_add_elt_complete);
 
   74     v_num = v_num_update = act_counter();
 
  106   template <
typename V>
 
  107   static void add_e_line__(
const V &v, dal::bit_vector &r) {
 
  108     typedef typename gmm::linalg_traits<V>::value_type T;
 
  109     typename gmm::linalg_traits<V>::const_iterator it = gmm::vect_begin(v);
 
  110     typename gmm::linalg_traits<V>::const_iterator ite = gmm::vect_end(v);
 
  111     for (; it != ite; ++it) 
if (*it != T(0)) r.add(it.index());
 
  117       if (
nb_dof() == 0) 
return dal::bit_vector();
 
  118       dal::bit_vector basic = res;
 
  120       for (dal::bv_visitor i(basic); !i.finished(); ++i)
 
  121         add_e_line__(gmm::mat_row(E_, i), res);
 
  128     GMM_ASSERT1(linked_mesh_ != 0, 
"Uninitialized mesh_fem");
 
  131       if (fe_convex.is_in(cv)) {
 
  133         dof_enumeration_made = 
false;
 
  134         touch(); v_num = act_counter();
 
  139                   == pf->basic_structure(cv),
 
  140                   "Incompatibility between fem " << 
name_of_fem(pf) <<
 
  141                   " and mesh element " <<
 
  142                   name_of_geometric_trans(linked_mesh_->trans_of_convex(cv)));
 
  143       GMM_ASSERT1((Qdim % pf->target_dim()) == 0 || pf->target_dim() == 1,
 
  144                   "Incompatibility between Qdim=" << 
int(Qdim) <<
 
  145                   " and target_dim " << 
int(pf->target_dim()) << 
" of " <<
 
  149       if (cv == f_elems.size()) {
 
  150         f_elems.push_back(pf);
 
  152         dof_enumeration_made = 
false;
 
  153         touch(); v_num = act_counter();
 
  155         if (cv > f_elems.size()) f_elems.resize(cv+1);
 
  156         if (!fe_convex.is_in(cv) || f_elems[cv] != pf) {
 
  159           dof_enumeration_made = 
false;
 
  160           touch(); v_num = act_counter();
 
  167     for (dal::bv_visitor cv(cvs); !cv.finished(); ++cv)
 
  178                                     fem_degree, complete);
 
  185     for (dal::bv_visitor cv(cvs); !cv.finished(); ++cv) {
 
  187                                       fem_degree, complete);
 
  200   (
size_type cv, dim_type fem_degree, scalar_type alpha, 
bool complete) {
 
  202       (
linked_mesh().trans_of_convex(cv), fem_degree, alpha, complete);
 
  207   (
const dal::bit_vector &cvs, dim_type fem_degree, scalar_type alpha,
 
  209     for (dal::bv_visitor cv(cvs); !cv.finished(); ++cv) {
 
  211         (
linked_mesh().trans_of_convex(cv), fem_degree, alpha, complete);
 
  217   (dim_type fem_degree, scalar_type alpha, 
bool complete) {
 
  225     pfem pf = f_elems[cv];
 
  226     return linked_mesh().trans_of_convex(cv)->transform
 
  227       (pf->node_of_dof(cv, i * pf->target_dim() / Qdim),
 
  236         pfem pf = f_elems[cv];
 
  237         return linked_mesh().trans_of_convex(cv)->transform
 
  242     GMM_ASSERT1(
false, 
"Inexistent dof");
 
  250         size_type tdim = f_elems[cv]->target_dim();
 
  251         return dim_type((d-i) / tdim);
 
  254     GMM_ASSERT1(
false, 
"Inexistent dof");
 
  273     GMM_ASSERT1(
false, 
"Inexistent dof");
 
  283     bool operator()(
const fem_dof& m, 
const fem_dof& n)
 const {
 
  284       if (m.ind_node < n.ind_node) 
return true;
 
  285       if (m.ind_node > n.ind_node) 
return false;
 
  286       if (m.part == n.part)
 
  288       else if (m.part < n.part) 
return true;
 
  295     ind.resize(nb_total_dof);
 
  297     for (dal::bv_visitor cv(
convex_index()); !cv.finished(); ++cv) {
 
  299       for (
size_type j=0; j < pf->nb_dof(cv); j++) {
 
  300         size_type gid = pf->index_of_global_dof(cv,j);
 
  303           for (
size_type i=0; i < Qdim/pf->target_dim(); ++i)
 
  310   bool mesh_fem::is_uniform()
 const {
 
  315   bool mesh_fem::is_uniformly_vectorized()
 const {
 
  317     return is_uniformly_vectorized_;
 
  324     is_uniformly_vectorized_ = (
get_qdim() > 1);
 
  325     GMM_ASSERT1(linked_mesh_ != 0, 
"Uninitialized mesh_fem");
 
  327     if (fe_convex.card() == 0)
 
  328       { dof_enumeration_made = 
true; nb_total_dof = 0; 
return; }
 
  329     pfem first_pf = f_elems[fe_convex.first_true()];
 
  330     if (first_pf && first_pf->is_on_real_element()) is_uniform_ = 
false;
 
  331     if (first_pf && first_pf->target_dim() > 1) is_uniformly_vectorized_=
false;
 
  338     std::vector<bgeot::kdtree> dof_nodes(nb_max_cv);
 
  339     std::vector<scalar_type> elt_car_sizes(nb_max_cv);
 
  340     std::vector<std::map<fem_dof, size_type, dof_comp_>> dof_sorts(nb_max_cv);
 
  343     dal::bit_vector encountered_global_dof, processed_elt;
 
  347     std::vector<size_type> itab;
 
  351     bgeot::mesh_structure::ind_set s;
 
  353     dof_structure.
clear();
 
  354     bgeot::pstored_point_tab pspt_old = 0;
 
  356     bgeot::pgeotrans_precomp pgp = 0;
 
  359          !cv.finished(); ++cv) {
 
  360       if (fe_convex.is_in(cv)) {
 
  361         gmm::copy(
linked_mesh().points_of_convex(cv)[0], bmin);
 
  362         gmm::copy(bmin, bmax);
 
  363         for (
const base_node &pt : 
linked_mesh().points_of_convex(cv)) {
 
  364           for (
size_type d = 1; d < bmin.size(); ++d) {
 
  365             bmin[d] = std::min(bmin[d], pt[d]);
 
  366             bmax[d] = std::max(bmax[d], pt[d]);
 
  369         elt_car_sizes[cv] = gmm::vect_dist2_sqr(bmin, bmax);
 
  373     dal::bit_vector cv_done;
 
  376          !cv.finished(); ++cv) { 
 
  377       if (!fe_convex.is_in(cv)) 
continue;
 
  379       if (pf != first_pf) is_uniform_ = 
false;
 
  380       if (pf->target_dim() > 1) is_uniformly_vectorized_ = 
false;
 
  382       bgeot::pstored_point_tab pspt = pf->node_tab(cv);
 
  383       if (pgt != pgt_old || pspt != pspt_old)
 
  384         pgp = bgeot::geotrans_precomp(pgt, pspt, pf);
 
  385       pgt_old = pgt; pspt_old = pspt;
 
  391         fd.pnd = pf->dof_types()[i];
 
  392         fd.part = get_dof_partition(cv);
 
  394         if (fd.pnd == andof) {              
 
  395           size_type num = pf->index_of_global_dof(cv, i);
 
  396           if (!(encountered_global_dof[num])) {
 
  397             ind_global_dof[num] = nbdof;
 
  398             nbdof += Qdim / pf->target_dim();
 
  399             encountered_global_dof[num] = 
true;
 
  401           itab[i] = ind_global_dof[num];
 
  404           nbdof += Qdim / pf->target_dim();
 
  406           pgp->transform(
linked_mesh().points_of_convex(cv), i, P);
 
  409           if (dof_nodes[cv].nb_points() > 0) {
 
  410             scalar_type dist = dof_nodes[cv].nearest_neighbor(ipt, P);
 
  411             if (gmm::abs(dist) <= 1e-6*elt_car_sizes[cv]) {
 
  413               auto it = dof_sorts[cv].find(fd);
 
  414               if (it != dof_sorts[cv].end()) idof = it->second;
 
  419             nbdof += Qdim / pf->target_dim();
 
  423               if (!cv_done[ncv] && fe_convex.is_in(ncv)) { 
 
  426                 if (dof_nodes[ncv].nb_points() > 0) {
 
  427                   scalar_type dist = dof_nodes[ncv].nearest_neighbor(ipt, P);
 
  428                   if (gmm::abs(dist) <= 1e-6*elt_car_sizes[ncv])
 
  432                   fd.ind_node = dof_nodes[ncv].add_point(P);
 
  433                 dof_sorts[ncv][fd] = idof;
 
  441       dof_sorts[cv].clear(); dof_nodes[cv].clear();
 
  442       dof_structure.add_convex_noverif(pf->structure(cv), itab.begin(), cv);
 
  445     dof_enumeration_made = 
true;
 
  446     nb_total_dof = nbdof;
 
  450     gmm::row_matrix<gmm::rsvector<scalar_type> >
 
  453     for (dal::bv_visitor i(kept_dof); !i.finished(); ++i, ++j)
 
  454       RR(j, i) = scalar_type(1);
 
  459     gmm::row_matrix<gmm::rsvector<scalar_type> >
 
  462     for (std::set<size_type>::const_iterator it = kept_dof.begin();
 
  463          it != kept_dof.end(); ++it, ++j)
 
  464       RR(j, *it) = scalar_type(1);
 
  468   void mesh_fem::clear() {
 
  470     dof_enumeration_made = 
false;
 
  472     touch(); v_num = act_counter();
 
  473     dof_structure.
clear();
 
  474     use_reduction = 
false;
 
  475     R_ = REDUCTION_MATRIX();
 
  476     E_ = EXTENSION_MATRIX();
 
  479   void mesh_fem::init_with_mesh(
const mesh &me, dim_type Q) {
 
  480     GMM_ASSERT1(linked_mesh_ == 0, 
"Mesh level set already initialized");
 
  481     dof_enumeration_made = 
false;
 
  484     auto_add_elt_K = dim_type(-1);
 
  486     mi.resize(1); mi[0] = Q;
 
  488     use_reduction = 
false;
 
  489     this->add_dependency(me);
 
  490     v_num = v_num_update = act_counter();
 
  493   void mesh_fem::copy_from(
const mesh_fem &mf) {
 
  494     clear_dependencies();
 
  496     init_with_mesh(*mf.linked_mesh_, mf.get_qdim());
 
  498     f_elems = mf.f_elems;
 
  499     fe_convex = mf.fe_convex;
 
  502     dof_structure = mf.dof_structure;
 
  503     dof_enumeration_made = mf.dof_enumeration_made;
 
  504     is_uniform_ = mf.is_uniform_;
 
  505     nb_total_dof = mf.nb_total_dof;
 
  506     auto_add_elt_pf = mf.auto_add_elt_pf;
 
  507     auto_add_elt_K = mf.auto_add_elt_K;
 
  508     auto_add_elt_disc = mf.auto_add_elt_disc;
 
  509     auto_add_elt_complete = mf.auto_add_elt_complete;
 
  510     auto_add_elt_alpha = mf.auto_add_elt_alpha;
 
  512     dof_partition = mf.dof_partition;
 
  513     v_num_update = mf.v_num_update;
 
  515     use_reduction = mf.use_reduction;
 
  518   mesh_fem::mesh_fem(
const mesh_fem &mf) : context_dependencies() {
 
  519     linked_mesh_ = 0; copy_from(mf);
 
  522   mesh_fem &mesh_fem::operator=(
const mesh_fem &mf) {
 
  527   mesh_fem::mesh_fem(
const mesh &me, dim_type Q)
 
  528     { linked_mesh_ = 0; init_with_mesh(me, Q); }
 
  530   mesh_fem::mesh_fem() {
 
  532     dof_enumeration_made = 
false;
 
  537   mesh_fem::~mesh_fem() { }
 
  540     GMM_ASSERT1(linked_mesh_ != 0, 
"Uninitialized mesh_fem");
 
  541     gmm::stream_standard_locale sl(ist);
 
  544     std::string tmp(
"nop"), tmp2(
"nop"); tmp.clear(); tmp2.clear();
 
  545     bool dof_read = 
false;
 
  546     gmm::col_matrix< gmm::wsvector<scalar_type> > RR, EE;
 
  549     ist.seekg(0);ist.clear();
 
  550     bgeot::read_until(ist, 
"BEGIN MESH_FEM");
 
  554       if (bgeot::casecmp(tmp, 
"END")==0) {
 
  556       } 
else if (bgeot::casecmp(tmp, 
"CONVEX")==0) {
 
  560                     " does not exist, are you sure " 
  561                     "that the mesh attached to this object is right one ?");
 
  566           while (!isspace(c)) { tmp.push_back(c); ist.get(c); }
 
  569         GMM_ASSERT1(
fem, 
"could not create the FEM '" << tmp << 
"'");
 
  571       } 
else if (bgeot::casecmp(tmp, 
"BEGIN")==0) {
 
  573         if (bgeot::casecmp(tmp, 
"DOF_PARTITION") == 0) {
 
  574           for (dal::bv_visitor cv(
convex_index()); !cv.finished(); ++cv) {
 
  575             size_type d; ist >> d; set_dof_partition(cv, 
unsigned(d));
 
  577           ist >> bgeot::skip(
"END DOF_PARTITION");
 
  578         } 
else if (bgeot::casecmp(tmp, 
"DOF_ENUMERATION") == 0) {
 
  579           dal::bit_vector doflst;
 
  580           dof_structure.
clear(); dof_enumeration_made = 
false;
 
  583           touch(); v_num = act_counter();
 
  586             if (bgeot::casecmp(tmp, 
"END")==0) {
 
  592             std::vector<size_type> tab;
 
  594                 isdigit(tmp[0]) && tmp2 == 
":") {
 
  598               else if (nbdof_unif != nbd)
 
  606                   doflst.add(tab[i]+q);
 
  608               dof_structure.add_convex_noverif
 
  610             } 
else GMM_ASSERT1(
false, 
"Missing convex or wrong number " 
  611                                << 
"in dof enumeration: '" 
  613                                << std::streamoff(ist.tellg())<<
"]");
 
  618           this->dof_enumeration_made = 
true;
 
  619           touch(); v_num = act_counter();
 
  620           this->nb_total_dof = doflst.card();
 
  621           ist >> bgeot::skip(
"DOF_ENUMERATION");
 
  622         } 
else if  (bgeot::casecmp(tmp, 
"REDUCTION_MATRIX")==0) {
 
  624           GMM_ASSERT1(bgeot::casecmp(tmp, 
"NROWS")==0,
 
  625                       "Missing number of rows");
 
  628           GMM_ASSERT1(bgeot::casecmp(tmp, 
"NCOLS")==0,
 
  629                       "Missing number of columns");
 
  632           GMM_ASSERT1(bgeot::casecmp(tmp, 
"NNZ")==0,
 
  633                       "Missing number of nonzero elements");
 
  635           gmm::clear(RR); gmm::resize(RR, nrows, ncols);
 
  638             GMM_ASSERT1(bgeot::casecmp(tmp, 
"COL")==0,
 
  639                         "Missing some columns");
 
  643               scalar_type val; ist >> val;
 
  647           R_ = REDUCTION_MATRIX(nrows, ncols);
 
  649           use_reduction = 
true;
 
  650           ist >> bgeot::skip(
"END");
 
  651           ist >> bgeot::skip(
"REDUCTION_MATRIX");
 
  652         } 
else if  (bgeot::casecmp(tmp, 
"EXTENSION_MATRIX")==0) {
 
  654           GMM_ASSERT1(bgeot::casecmp(tmp, 
"NROWS")==0,
 
  655                       "Missing number of rows");
 
  658           GMM_ASSERT1(bgeot::casecmp(tmp, 
"NCOLS")==0,
 
  659                       "Missing number of columns");
 
  662           GMM_ASSERT1(bgeot::casecmp(tmp, 
"NNZ")==0,
 
  663                       "Missing number of nonzero elements");
 
  665           gmm::clear(EE); gmm::resize(EE, nrows, ncols);
 
  668             GMM_ASSERT1(bgeot::casecmp(tmp, 
"ROW")==0,
 
  669                         "Missing some rows");
 
  673               scalar_type val; ist >> val;
 
  677           E_ = EXTENSION_MATRIX(nrows, ncols);
 
  679           use_reduction = 
true;
 
  680           ist >> bgeot::skip(
"END");
 
  681           ist >> bgeot::skip(
"EXTENSION_MATRIX");
 
  684           GMM_ASSERT1(
false, 
"Syntax error in file at token '" 
  685                       << tmp << 
"' [pos=" << std::streamoff(ist.tellg())
 
  687       } 
else if (bgeot::casecmp(tmp, 
"QDIM")==0) {
 
  688         GMM_ASSERT1(!dof_read, 
"Can't change QDIM after dof enumeration");
 
  690         int q = atoi(tmp.c_str());
 
  691         GMM_ASSERT1(q > 0 && q <= 250, 
"invalid qdim: " << q);
 
  693       } 
else if (tmp.size()) {
 
  694         GMM_ASSERT1(
false, 
"Unexpected token '" << tmp <<
 
  695                     "' [pos=" << std::streamoff(ist.tellg()) << 
"]");
 
  696       } 
else if (ist.eof()) {
 
  697         GMM_ASSERT1(
false, 
"Unexpected end of stream " 
  698                     << 
"(missing BEGIN MESH_FEM/END MESH_FEM ?)");
 
  704     std::ifstream o(name.c_str());
 
  705     GMM_ASSERT1(o, 
"Mesh_fem file '" << name << 
"' does not exist");
 
  709   template<
typename VECT> 
static void 
  710   write_col(std::ostream &ost, 
const VECT &v) {
 
  711     typename gmm::linalg_traits<VECT>::const_iterator it = v.begin();
 
  713     for (; it != v.end(); ++it)
 
  714       ost << 
" " << it.index() << 
" " << *it;
 
  718   void mesh_fem::write_reduction_matrices_to_file(std::ostream &ost)
 const {
 
  721       ost << 
" BEGIN REDUCTION_MATRIX " << 
'\n';
 
  722       ost << 
"  NROWS " <<  gmm::mat_nrows(R_) << 
'\n';
 
  723       ost << 
"  NCOLS " <<  gmm::mat_ncols(R_) << 
'\n';
 
  724       ost << 
"  NNZ " << gmm::nnz(R_) << 
'\n';
 
  725       for (
size_type i = 0; i < gmm::mat_ncols(R_); ++i) {
 
  727         write_col(ost, gmm::mat_col(R_, i));
 
  729       ost << 
" END REDUCTION_MATRIX " << 
'\n';
 
  730       ost << 
" BEGIN EXTENSION_MATRIX " << 
'\n';
 
  731       ost << 
"  NROWS " <<  gmm::mat_nrows(E_) << 
'\n';
 
  732       ost << 
"  NCOLS " <<  gmm::mat_ncols(E_) << 
'\n';
 
  733       ost << 
"  NNZ " << 
gmm::nnz(E_) << 
'\n';
 
  734       for (
size_type i = 0; i < gmm::mat_nrows(E_); ++i) {
 
  736         write_col(ost, gmm::mat_row(E_, i));
 
  738       ost << 
" END EXTENSION_MATRIX " << 
'\n';
 
  742   void mesh_fem::write_basic_to_file(std::ostream &ost)
 const {
 
  744     for (dal::bv_visitor cv(
convex_index()); !cv.finished(); ++cv) {
 
  745       ost << 
" CONVEX " << cv;
 
  750     if (!dof_partition.empty()) {
 
  751       ost << 
" BEGIN DOF_PARTITION\n";
 
  753       for (dal::bv_visitor cv(
convex_index()); !cv.finished(); ++cv) {
 
  754         ost << 
" " << get_dof_partition(cv); 
if ((++i % 20) == 0) ost << 
"\n";
 
  757       ost << 
" END DOF_PARTITION\n";
 
  760     ost << 
" BEGIN DOF_ENUMERATION " << 
'\n';
 
  761     for (dal::bv_visitor cv(
convex_index()); !cv.finished(); ++cv) {
 
  762       ost << 
"  " << cv << 
": ";
 
  773     ost << 
" END DOF_ENUMERATION " << 
'\n';
 
  778     gmm::stream_standard_locale sl(ost);
 
  779     ost << 
'\n' << 
"BEGIN MESH_FEM" << 
'\n' << 
'\n';
 
  780     write_basic_to_file(ost);
 
  781     write_reduction_matrices_to_file(ost);
 
  782     ost << 
"END MESH_FEM" << 
'\n';
 
  786     std::ofstream o(name.c_str());
 
  787     GMM_ASSERT1(o, 
"impossible to open file '" << name << 
"'");
 
  788     o << 
"% GETFEM MESH_FEM FILE " << 
'\n';
 
  789     o << 
"% GETFEM VERSION " << GETFEM_VERSION << 
'\n' << 
'\n' << 
'\n';
 
  796     dim_type order, qdim;
 
  798     mf__key_(
const mesh &msh, dim_type o, dim_type q, 
bool complete_)
 
  799       : pmsh(&msh), order(o), qdim(q), complete(complete_)
 
  800     { add_dependency(msh); }
 
  801     bool operator <(
const mf__key_ &a)
 const {
 
  802       if (pmsh < a.pmsh) 
return true;
 
  803       else if (pmsh > a.pmsh) 
return false;
 
  804       else if (order < a.order) 
return true;
 
  805       else if (order > a.order) 
return false;
 
  806       else if (qdim < a.qdim) 
return true;
 
  807       else if (qdim > a.qdim) 
return false;
 
  808       else if (complete < a.complete) 
return true;
 
  811     void update_from_context()
 const {}
 
  812     mf__key_(
const mf__key_ &mfk) : context_dependencies( ) {
 
  816       complete = mfk.complete;
 
  817       add_dependency(*pmsh);
 
  820     mf__key_& operator=(
const mf__key_ &mfk);
 
  824   class classical_mesh_fem_pool {
 
  826     typedef std::shared_ptr<const mesh_fem> pmesh_fem;
 
  827     typedef std::map<mf__key_, pmesh_fem> mesh_fem_tab;
 
  833     const mesh_fem &operator()(
const mesh &msh, dim_type o, dim_type qdim,
 
  834                                bool complete=
false) {
 
  835       mesh_fem_tab::iterator itt = mfs.begin(), itn = mfs.begin();
 
  836       if (itn != mfs.end()) itn++;
 
  837       while (itt != mfs.end()) {
 
  838         if (!(itt->first.is_context_valid()))
 
  841         if (itn != mfs.end()) itn++;
 
  844       mf__key_ key(msh, o, qdim, complete);
 
  845       mesh_fem_tab::iterator it = mfs.find(key);
 
  846       assert(it == mfs.end() || it->second->is_context_valid());
 
  848       if (it == mfs.end()) {
 
  850         auto pmf = (p_torus_mesh) ? std::make_shared<torus_mesh_fem>(*p_torus_mesh, qdim)
 
  851                                   : std::make_shared<mesh_fem>(msh, qdim);
 
  852         pmf->set_classical_finite_element(o);
 
  853         pmf->set_auto_add(o, 
false);
 
  854         return *(mfs[key] = pmf);
 
  856       else return *(it->second);
 
  862                                      dim_type order, dim_type qdim,
 
  864     classical_mesh_fem_pool &pool
 
  866     return pool(msh, order, qdim, complete);
 
  869   struct dummy_mesh_fem_ {
 
  871     dummy_mesh_fem_() : mf(dummy_mesh()) {}
 
  878   void vectorize_base_tensor(
const base_tensor &t, base_matrix &vt,
 
  880     GMM_ASSERT1(qdim == N || qdim == 1, 
"mixed intrinsic vector and " 
  881                 "tensorised fem is not supported");
 
  882     gmm::resize(vt, ndof, N);
 
  883     ndof = (ndof*qdim)/N;
 
  886       gmm::copy(t.as_vector(), vt.as_vector());
 
  887     } 
else if (qdim == 1) {
 
  889       base_tensor::const_iterator it = t.begin();
 
  890       for (
size_type i = 0; i < ndof; ++i, ++it)
 
  891         for (
size_type j = 0; j < N; ++j) vt(i*N+j, j) = *it;
 
  895   void vectorize_grad_base_tensor(
const base_tensor &t, base_tensor &vt,
 
  898     GMM_ASSERT1(qdim == Q || qdim == 1, 
"mixed intrinsic vector and " 
  899                   "tensorised fem is not supported");
 
  900     vt.adjust_sizes(bgeot::multi_index(ndof, Q, N));
 
  901     ndof = (ndof*qdim)/Q;
 
  904       gmm::copy(t.as_vector(), vt.as_vector());
 
  905     } 
else if (qdim == 1) {
 
  907       base_tensor::const_iterator it = t.begin();
 
  909         for (
size_type i = 0; i < ndof; ++i, ++it)
 
  910           for (
size_type j = 0; j < Q; ++j) vt(i*Q+j, j, k) = *it;
 
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.
 
void clear()
erase the mesh
 
ind_pt_face_ct ind_points_of_face_of_convex(size_type ic, short_type f) const
Return a container of the (global) point number for face f or convex ic.
 
void neighbors_of_convex(size_type ic, short_type f, ind_set &s) const
Return in s a list of neighbors of a given convex face.
 
const ind_cv_ct & convex_to_point(size_type ip) const
Return a container of the convexes attached to point ip.
 
size_type first_convex_of_point(size_type ip) const
Convex ID of the first convex attached to the point ip.
 
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
 
size_type ind_in_convex_of_point(size_type ic, size_type ip) const
Find the local index of the point of global index ip with respect to the convex cv.
 
const ind_set & ind_points_of_convex(size_type ic) const
Return a container to the list of points attached to convex ic.
 
size_type nb_allocated_convex() const
The number of convex indexes from 0 to the index of the last convex.
 
static T & instance()
Instance from the current thread.
 
Deal with interdependencies of objects.
 
bool context_check() const
return true if update_from_context was called
 
virtual_fem implementation as a vector of generic functions.
 
Describe a finite element method linked to a mesh.
 
virtual ind_dof_ct ind_basic_dof_of_element(size_type cv) const
Give an array of the dof numbers a of convex.
 
void set_classical_discontinuous_finite_element(size_type cv, dim_type fem_degree, scalar_type alpha=0, bool complete=false)
Similar to set_classical_finite_element, but uses discontinuous lagrange elements.
 
void set_auto_add(dim_type K, bool disc=false, scalar_type alpha=scalar_type(0), bool complete=false)
Set the degree of the fem for automatic addition of element option.
 
virtual void get_global_dof_index(std::vector< size_type > &ind) const
Give an array that contains the global dof indices corresponding to the mesh_fem dofs or size_type(-1...
 
void reduce_to_basic_dof(const dal::bit_vector &kept_basic_dof)
Allows to set the reduction and the extension matrices in order to keep only a certain number of dof.
 
virtual void enumerate_dof() const
Renumber the degrees of freedom.
 
virtual size_type first_convex_of_basic_dof(size_type d) const
Shortcut for convex_to_dof(d)[0].
 
virtual dim_type get_qdim() const
Return the Q dimension.
 
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
 
virtual dim_type basic_dof_qdim(size_type d) const
Return the dof component number (0<= x <Qdim)
 
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
 
void update_from_context() const
this function has to be defined and should update the object when the context is modified.
 
virtual void read_from_file(std::istream &ist)
Read the mesh_fem from a stream.
 
void set_finite_element(size_type cv, pfem pf)
Set the finite element method of a convex.
 
virtual void write_to_file(std::ostream &ost) const
Write the mesh_fem to a stream.
 
void set_reduction_matrices(const MATR &RR, const MATE &EE)
Allows to set the reduction and the extension matrices.
 
virtual size_type nb_basic_dof() const
Return the total number of basic degrees of freedom (before the optional reduction).
 
virtual dal::bit_vector basic_dof_on_region(const mesh_region &b) const
Get a list of basic dof lying on a given mesh_region.
 
virtual void set_qdim(dim_type q)
Change the Q dimension.
 
virtual base_node point_of_basic_dof(size_type cv, size_type i) const
Return the geometrical location of a degree of freedom.
 
void set_classical_finite_element(size_type cv, dim_type fem_degree, bool complete=false)
Set a classical (i.e.
 
virtual pfem fem_of_element(size_type cv) const
Return the basic fem associated with an element (if no fem is associated, the function will crash!...
 
const dal::bit_vector & convex_index() const
Get the set of convexes where a finite element has been assigned.
 
dal::bit_vector dof_on_region(const mesh_region &b) const
Get a list of dof lying on a given mesh_region.
 
virtual size_type nb_basic_dof_of_element(size_type cv) const
Return the number of degrees of freedom attached to a given convex.
 
bool is_reduced() const
Return true if a reduction matrix is applied to the dofs.
 
virtual const mesh::ind_cv_ct & convex_to_basic_dof(size_type d) const
Return the list of convexes attached to the specified dof.
 
"iterator" class for regions.
 
structure used to hold a set of convexes and/or convex faces.
 
Describe a mesh (collection of convexes (elements) and points).
 
void write_to_file(const std::string &name) const
Write the mesh to a file.
 
gmm::uint64_type convex_version_number(size_type ic) const
return the version number of the convex ic.
 
Copy an original 2D mesh to become a torus mesh with radial dimension.
 
A simple singleton implementation.
 
Define the getfem::mesh_fem class.
 
Provides mesh and mesh fem of torus.
 
size_type nnz(const L &l)
count the number of non-zero entries of a vector or matrix.
 
void copy(const L1 &l1, L2 &l2)
*/
 
void clear(L &l)
clear (fill with zeros) a vector or matrix.
 
int dof_description_compare(pdof_description a, pdof_description b)
Gives a total order on the dof description compatible with the identification.
 
bool dof_linkable(pdof_description)
Says if the dof is linkable.
 
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 fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
 
pfem classical_discontinuous_fem(bgeot::pgeometric_trans pg, short_type k, scalar_type alpha=0, bool complete=false)
Give a pointer on the structures describing the classical polynomial discontinuous fem of degree k on...
 
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...
 
std::string name_of_fem(pfem p)
get the string name of a fem descriptor.
 
gmm::uint16_type short_type
used as the common short type integer in the library
 
int get_token(std::istream &ist, std::string &st, bool ignore_cr, bool to_up, bool read_un_pm, int *linenb)
Very simple lexical analysis of general interest for reading small languages with a "MATLAB like" syn...
 
size_t size_type
used as the common size type in the library
 
pconvex_structure basic_structure(pconvex_structure cv)
Original structure (if concerned)
 
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
 
GEneric Tool for Finite Element Methods.
 
const mesh_fem & dummy_mesh_fem()
Dummy mesh_fem for default parameter of functions.
 
const mesh_fem & classical_mesh_fem(const mesh &mesh, dim_type degree, dim_type qdim=1, bool complete=false)
Gives the descriptor of a classical finite element method of degree K on mesh.
 
store a point and the associated index for the kdtree.