30 for (dal::bv_visitor cv(fe_convex); !cv.finished(); ++cv) {
32 if (v_num_update < linked_mesh_->convex_version_number(cv)) {
33 if (auto_add_elt_pf != 0)
36 else if (auto_add_elt_K != dim_type(-1)) {
37 if (auto_add_elt_disc)
40 (cv, auto_add_elt_K, auto_add_elt_alpha,
41 auto_add_elt_complete);
45 auto_add_elt_complete);
54 !cv.finished(); ++cv) {
55 if (!fe_convex.is_in(cv)
57 if (auto_add_elt_pf != 0)
60 else if (auto_add_elt_K != dim_type(-1)) {
61 if (auto_add_elt_disc)
64 (cv, auto_add_elt_K, auto_add_elt_alpha, auto_add_elt_complete);
68 auto_add_elt_complete);
73 v_num = v_num_update = act_counter();
105 template <
typename V>
106 static void add_e_line__(
const V &v, dal::bit_vector &r) {
107 typedef typename gmm::linalg_traits<V>::value_type T;
108 typename gmm::linalg_traits<V>::const_iterator it = gmm::vect_begin(v);
109 typename gmm::linalg_traits<V>::const_iterator ite = gmm::vect_end(v);
110 for (; it != ite; ++it)
if (*it != T(0)) r.add(it.index());
116 if (
nb_dof() == 0)
return dal::bit_vector();
117 dal::bit_vector basic = res;
119 for (dal::bv_visitor i(basic); !i.finished(); ++i)
120 add_e_line__(gmm::mat_row(E_, i), res);
127 GMM_ASSERT1(linked_mesh_ != 0,
"Uninitialized mesh_fem");
130 if (fe_convex.is_in(cv)) {
132 dof_enumeration_made =
false;
133 touch(); v_num = act_counter();
138 == pf->basic_structure(cv),
139 "Incompatibility between fem " <<
name_of_fem(pf) <<
140 " and mesh element " <<
141 name_of_geometric_trans(linked_mesh_->trans_of_convex(cv)));
142 GMM_ASSERT1((Qdim % pf->target_dim()) == 0 || pf->target_dim() == 1,
143 "Incompatibility between Qdim=" <<
int(Qdim) <<
144 " and target_dim " <<
int(pf->target_dim()) <<
" of " <<
148 if (cv == f_elems.size()) {
149 f_elems.push_back(pf);
151 dof_enumeration_made =
false;
152 touch(); v_num = act_counter();
154 if (cv > f_elems.size()) f_elems.resize(cv+1);
155 if (!fe_convex.is_in(cv) || f_elems[cv] != pf) {
158 dof_enumeration_made =
false;
159 touch(); v_num = act_counter();
166 for (dal::bv_visitor cv(cvs); !cv.finished(); ++cv)
177 fem_degree, complete);
184 for (dal::bv_visitor cv(cvs); !cv.finished(); ++cv) {
186 fem_degree, complete);
199 (
size_type cv, dim_type fem_degree, scalar_type alpha,
bool complete) {
201 (
linked_mesh().trans_of_convex(cv), fem_degree, alpha, complete);
206 (
const dal::bit_vector &cvs, dim_type fem_degree, scalar_type alpha,
208 for (dal::bv_visitor cv(cvs); !cv.finished(); ++cv) {
210 (
linked_mesh().trans_of_convex(cv), fem_degree, alpha, complete);
216 (dim_type fem_degree, scalar_type alpha,
bool complete) {
224 pfem pf = f_elems[cv];
225 return linked_mesh().trans_of_convex(cv)->transform
226 (pf->node_of_dof(cv, i * pf->target_dim() / Qdim),
235 pfem pf = f_elems[cv];
236 return linked_mesh().trans_of_convex(cv)->transform
241 GMM_ASSERT1(
false,
"Inexistent dof");
249 size_type tdim = f_elems[cv]->target_dim();
250 return dim_type((d-i) / tdim);
253 GMM_ASSERT1(
false,
"Inexistent dof");
272 GMM_ASSERT1(
false,
"Inexistent dof");
282 bool operator()(
const fem_dof& m,
const fem_dof& n)
const {
283 if (m.ind_node < n.ind_node)
return true;
284 if (m.ind_node > n.ind_node)
return false;
285 if (m.part == n.part)
287 else if (m.part < n.part)
return true;
294 ind.resize(nb_total_dof);
296 for (dal::bv_visitor cv(
convex_index()); !cv.finished(); ++cv) {
298 for (
size_type j=0; j < pf->nb_dof(cv); j++) {
299 size_type gid = pf->index_of_global_dof(cv,j);
302 for (
size_type i=0; i < Qdim/pf->target_dim(); ++i)
309 bool mesh_fem::is_uniform()
const {
314 bool mesh_fem::is_uniformly_vectorized()
const {
316 return is_uniformly_vectorized_;
323 is_uniformly_vectorized_ = (
get_qdim() > 1);
324 GMM_ASSERT1(linked_mesh_ != 0,
"Uninitialized mesh_fem");
326 if (fe_convex.card() == 0)
327 { dof_enumeration_made =
true; nb_total_dof = 0;
return; }
328 pfem first_pf = f_elems[fe_convex.first_true()];
329 if (first_pf && first_pf->is_on_real_element()) is_uniform_ =
false;
330 if (first_pf && first_pf->target_dim() > 1) is_uniformly_vectorized_=
false;
337 std::vector<bgeot::kdtree> dof_nodes(nb_max_cv);
338 std::vector<scalar_type> elt_car_sizes(nb_max_cv);
339 std::vector<std::map<fem_dof, size_type, dof_comp_>> dof_sorts(nb_max_cv);
342 dal::bit_vector encountered_global_dof, processed_elt;
346 std::vector<size_type> itab;
350 bgeot::mesh_structure::ind_set s;
352 dof_structure.
clear();
353 bgeot::pstored_point_tab pspt_old = 0;
355 bgeot::pgeotrans_precomp pgp = 0;
358 !cv.finished(); ++cv) {
359 if (fe_convex.is_in(cv)) {
360 gmm::copy(
linked_mesh().points_of_convex(cv)[0], bmin);
361 gmm::copy(bmin, bmax);
362 for (
const base_node &pt :
linked_mesh().points_of_convex(cv)) {
363 for (
size_type d = 1; d < bmin.size(); ++d) {
364 bmin[d] = std::min(bmin[d], pt[d]);
365 bmax[d] = std::max(bmax[d], pt[d]);
368 elt_car_sizes[cv] = gmm::vect_dist2_sqr(bmin, bmax);
372 dal::bit_vector cv_done;
375 !cv.finished(); ++cv) {
376 if (!fe_convex.is_in(cv))
continue;
378 if (pf != first_pf) is_uniform_ =
false;
379 if (pf->target_dim() > 1) is_uniformly_vectorized_ =
false;
381 bgeot::pstored_point_tab pspt = pf->node_tab(cv);
382 if (pgt != pgt_old || pspt != pspt_old)
383 pgp = bgeot::geotrans_precomp(pgt, pspt, pf);
384 pgt_old = pgt; pspt_old = pspt;
390 fd.pnd = pf->dof_types()[i];
391 fd.part = get_dof_partition(cv);
393 if (fd.pnd == andof) {
394 size_type num = pf->index_of_global_dof(cv, i);
395 if (!(encountered_global_dof[num])) {
396 ind_global_dof[num] = nbdof;
397 nbdof += Qdim / pf->target_dim();
398 encountered_global_dof[num] =
true;
400 itab[i] = ind_global_dof[num];
403 nbdof += Qdim / pf->target_dim();
405 pgp->transform(
linked_mesh().points_of_convex(cv), i, P);
408 if (dof_nodes[cv].nb_points() > 0) {
409 scalar_type dist = dof_nodes[cv].nearest_neighbor(ipt, P);
410 if (gmm::abs(dist) <= 1e-6*elt_car_sizes[cv]) {
412 auto it = dof_sorts[cv].find(fd);
413 if (it != dof_sorts[cv].end()) idof = it->second;
418 nbdof += Qdim / pf->target_dim();
422 if (!cv_done[ncv] && fe_convex.is_in(ncv)) {
425 if (dof_nodes[ncv].nb_points() > 0) {
426 scalar_type dist = dof_nodes[ncv].nearest_neighbor(ipt, P);
427 if (gmm::abs(dist) <= 1e-6*elt_car_sizes[ncv])
431 fd.ind_node = dof_nodes[ncv].add_point(P);
432 dof_sorts[ncv][fd] = idof;
440 dof_sorts[cv].clear(); dof_nodes[cv].clear();
441 dof_structure.add_convex_noverif(pf->structure(cv), itab.begin(), cv);
444 dof_enumeration_made =
true;
445 nb_total_dof = nbdof;
449 gmm::row_matrix<gmm::rsvector<scalar_type> >
452 for (dal::bv_visitor i(kept_dof); !i.finished(); ++i, ++j)
453 RR(j, i) = scalar_type(1);
458 gmm::row_matrix<gmm::rsvector<scalar_type> >
461 for (std::set<size_type>::const_iterator it = kept_dof.begin();
462 it != kept_dof.end(); ++it, ++j)
463 RR(j, *it) = scalar_type(1);
467 void mesh_fem::clear() {
469 dof_enumeration_made =
false;
471 touch(); v_num = act_counter();
472 dof_structure.
clear();
473 use_reduction =
false;
474 R_ = REDUCTION_MATRIX();
475 E_ = EXTENSION_MATRIX();
478 void mesh_fem::init_with_mesh(
const mesh &me, dim_type Q) {
479 GMM_ASSERT1(linked_mesh_ == 0,
"Mesh level set already initialized");
480 dof_enumeration_made =
false;
483 auto_add_elt_K = dim_type(-1);
485 mi.resize(1); mi[0] = Q;
487 use_reduction =
false;
488 this->add_dependency(me);
489 v_num = v_num_update = act_counter();
492 void mesh_fem::copy_from(
const mesh_fem &mf) {
493 clear_dependencies();
495 init_with_mesh(*mf.linked_mesh_, mf.get_qdim());
497 f_elems = mf.f_elems;
498 fe_convex = mf.fe_convex;
501 dof_structure = mf.dof_structure;
502 dof_enumeration_made = mf.dof_enumeration_made;
503 is_uniform_ = mf.is_uniform_;
504 nb_total_dof = mf.nb_total_dof;
505 auto_add_elt_pf = mf.auto_add_elt_pf;
506 auto_add_elt_K = mf.auto_add_elt_K;
507 auto_add_elt_disc = mf.auto_add_elt_disc;
508 auto_add_elt_complete = mf.auto_add_elt_complete;
509 auto_add_elt_alpha = mf.auto_add_elt_alpha;
511 dof_partition = mf.dof_partition;
512 v_num_update = mf.v_num_update;
514 use_reduction = mf.use_reduction;
517 mesh_fem::mesh_fem(
const mesh_fem &mf) : context_dependencies() {
518 linked_mesh_ = 0; copy_from(mf);
521 mesh_fem &mesh_fem::operator=(
const mesh_fem &mf) {
526 mesh_fem::mesh_fem(
const mesh &me, dim_type Q)
527 { linked_mesh_ = 0; init_with_mesh(me, Q); }
529 mesh_fem::mesh_fem() {
531 dof_enumeration_made =
false;
536 mesh_fem::~mesh_fem() { }
539 GMM_ASSERT1(linked_mesh_ != 0,
"Uninitialized mesh_fem");
540 gmm::stream_standard_locale sl(ist);
543 std::string tmp(
"nop"), tmp2(
"nop"); tmp.clear(); tmp2.clear();
544 bool dof_read =
false;
545 gmm::col_matrix< gmm::wsvector<scalar_type> > RR, EE;
548 ist.seekg(0);ist.clear();
549 bgeot::read_until(ist,
"BEGIN MESH_FEM");
553 if (bgeot::casecmp(tmp,
"END")==0) {
555 }
else if (bgeot::casecmp(tmp,
"CONVEX")==0) {
559 " does not exist, are you sure "
560 "that the mesh attached to this object is right one ?");
565 while (!isspace(c)) { tmp.push_back(c); ist.get(c); }
568 GMM_ASSERT1(
fem,
"could not create the FEM '" << tmp <<
"'");
570 }
else if (bgeot::casecmp(tmp,
"BEGIN")==0) {
572 if (bgeot::casecmp(tmp,
"DOF_PARTITION") == 0) {
573 for (dal::bv_visitor cv(
convex_index()); !cv.finished(); ++cv) {
574 size_type d; ist >> d; set_dof_partition(cv,
unsigned(d));
576 ist >> bgeot::skip(
"END DOF_PARTITION");
577 }
else if (bgeot::casecmp(tmp,
"DOF_ENUMERATION") == 0) {
578 dal::bit_vector doflst;
579 dof_structure.
clear(); dof_enumeration_made =
false;
582 touch(); v_num = act_counter();
585 if (bgeot::casecmp(tmp,
"END")==0) {
591 std::vector<size_type> tab;
593 isdigit(tmp[0]) && tmp2 ==
":") {
597 else if (nbdof_unif != nbd)
605 doflst.add(tab[i]+q);
607 dof_structure.add_convex_noverif
609 }
else GMM_ASSERT1(
false,
"Missing convex or wrong number "
610 <<
"in dof enumeration: '"
612 << std::streamoff(ist.tellg())<<
"]");
617 this->dof_enumeration_made =
true;
618 touch(); v_num = act_counter();
619 this->nb_total_dof = doflst.card();
620 ist >> bgeot::skip(
"DOF_ENUMERATION");
621 }
else if (bgeot::casecmp(tmp,
"REDUCTION_MATRIX")==0) {
623 GMM_ASSERT1(bgeot::casecmp(tmp,
"NROWS")==0,
624 "Missing number of rows");
627 GMM_ASSERT1(bgeot::casecmp(tmp,
"NCOLS")==0,
628 "Missing number of columns");
631 GMM_ASSERT1(bgeot::casecmp(tmp,
"NNZ")==0,
632 "Missing number of nonzero elements");
634 gmm::clear(RR); gmm::resize(RR, nrows, ncols);
637 GMM_ASSERT1(bgeot::casecmp(tmp,
"COL")==0,
638 "Missing some columns");
642 scalar_type val; ist >> val;
646 R_ = REDUCTION_MATRIX(nrows, ncols);
648 use_reduction =
true;
649 ist >> bgeot::skip(
"END");
650 ist >> bgeot::skip(
"REDUCTION_MATRIX");
651 }
else if (bgeot::casecmp(tmp,
"EXTENSION_MATRIX")==0) {
653 GMM_ASSERT1(bgeot::casecmp(tmp,
"NROWS")==0,
654 "Missing number of rows");
657 GMM_ASSERT1(bgeot::casecmp(tmp,
"NCOLS")==0,
658 "Missing number of columns");
661 GMM_ASSERT1(bgeot::casecmp(tmp,
"NNZ")==0,
662 "Missing number of nonzero elements");
664 gmm::clear(EE); gmm::resize(EE, nrows, ncols);
667 GMM_ASSERT1(bgeot::casecmp(tmp,
"ROW")==0,
668 "Missing some rows");
672 scalar_type val; ist >> val;
676 E_ = EXTENSION_MATRIX(nrows, ncols);
678 use_reduction =
true;
679 ist >> bgeot::skip(
"END");
680 ist >> bgeot::skip(
"EXTENSION_MATRIX");
683 GMM_ASSERT1(
false,
"Syntax error in file at token '"
684 << tmp <<
"' [pos=" << std::streamoff(ist.tellg())
686 }
else if (bgeot::casecmp(tmp,
"QDIM")==0) {
687 GMM_ASSERT1(!dof_read,
"Can't change QDIM after dof enumeration");
689 int q = atoi(tmp.c_str());
690 GMM_ASSERT1(q > 0 && q <= 250,
"invalid qdim: " << q);
692 }
else if (tmp.size()) {
693 GMM_ASSERT1(
false,
"Unexpected token '" << tmp <<
694 "' [pos=" << std::streamoff(ist.tellg()) <<
"]");
695 }
else if (ist.eof()) {
696 GMM_ASSERT1(
false,
"Unexpected end of stream "
697 <<
"(missing BEGIN MESH_FEM/END MESH_FEM ?)");
703 std::ifstream o(name.c_str());
704 GMM_ASSERT1(o,
"Mesh_fem file '" << name <<
"' does not exist");
708 template<
typename VECT>
static void
709 write_col(std::ostream &ost,
const VECT &v) {
710 typename gmm::linalg_traits<VECT>::const_iterator it = v.begin();
712 for (; it != v.end(); ++it)
713 ost <<
" " << it.index() <<
" " << *it;
717 void mesh_fem::write_reduction_matrices_to_file(std::ostream &ost)
const {
720 ost <<
" BEGIN REDUCTION_MATRIX " <<
'\n';
721 ost <<
" NROWS " << gmm::mat_nrows(R_) <<
'\n';
722 ost <<
" NCOLS " << gmm::mat_ncols(R_) <<
'\n';
723 ost <<
" NNZ " << gmm::nnz(R_) <<
'\n';
724 for (
size_type i = 0; i < gmm::mat_ncols(R_); ++i) {
726 write_col(ost, gmm::mat_col(R_, i));
728 ost <<
" END REDUCTION_MATRIX " <<
'\n';
729 ost <<
" BEGIN EXTENSION_MATRIX " <<
'\n';
730 ost <<
" NROWS " << gmm::mat_nrows(E_) <<
'\n';
731 ost <<
" NCOLS " << gmm::mat_ncols(E_) <<
'\n';
732 ost <<
" NNZ " <<
gmm::nnz(E_) <<
'\n';
733 for (
size_type i = 0; i < gmm::mat_nrows(E_); ++i) {
735 write_col(ost, gmm::mat_row(E_, i));
737 ost <<
" END EXTENSION_MATRIX " <<
'\n';
741 void mesh_fem::write_basic_to_file(std::ostream &ost)
const {
743 for (dal::bv_visitor cv(
convex_index()); !cv.finished(); ++cv) {
744 ost <<
" CONVEX " << cv;
749 if (!dof_partition.empty()) {
750 ost <<
" BEGIN DOF_PARTITION\n";
752 for (dal::bv_visitor cv(
convex_index()); !cv.finished(); ++cv) {
753 ost <<
" " << get_dof_partition(cv);
if ((++i % 20) == 0) ost <<
"\n";
756 ost <<
" END DOF_PARTITION\n";
759 ost <<
" BEGIN DOF_ENUMERATION " <<
'\n';
760 for (dal::bv_visitor cv(
convex_index()); !cv.finished(); ++cv) {
761 ost <<
" " << cv <<
": ";
772 ost <<
" END DOF_ENUMERATION " <<
'\n';
777 gmm::stream_standard_locale sl(ost);
778 ost <<
'\n' <<
"BEGIN MESH_FEM" <<
'\n' <<
'\n';
779 write_basic_to_file(ost);
780 write_reduction_matrices_to_file(ost);
781 ost <<
"END MESH_FEM" <<
'\n';
785 std::ofstream o(name.c_str());
786 GMM_ASSERT1(o,
"impossible to open file '" << name <<
"'");
787 o <<
"% GETFEM MESH_FEM FILE " <<
'\n';
788 o <<
"% GETFEM VERSION " << GETFEM_VERSION <<
'\n' <<
'\n' <<
'\n';
795 dim_type order, qdim;
797 mf__key_(
const mesh &msh, dim_type o, dim_type q,
bool complete_)
798 : pmsh(&msh), order(o), qdim(q), complete(complete_)
799 { add_dependency(msh); }
800 bool operator <(
const mf__key_ &a)
const {
801 if (pmsh < a.pmsh)
return true;
802 else if (pmsh > a.pmsh)
return false;
803 else if (order < a.order)
return true;
804 else if (order > a.order)
return false;
805 else if (qdim < a.qdim)
return true;
806 else if (qdim > a.qdim)
return false;
807 else if (complete < a.complete)
return true;
810 void update_from_context()
const {}
811 mf__key_(
const mf__key_ &mfk) : context_dependencies( ) {
815 complete = mfk.complete;
816 add_dependency(*pmsh);
819 mf__key_& operator=(
const mf__key_ &mfk);
823 class classical_mesh_fem_pool {
825 typedef std::shared_ptr<const mesh_fem> pmesh_fem;
826 typedef std::map<mf__key_, pmesh_fem> mesh_fem_tab;
832 const mesh_fem &operator()(
const mesh &msh, dim_type o, dim_type qdim,
833 bool complete=
false) {
834 mesh_fem_tab::iterator itt = mfs.begin(), itn = mfs.begin();
835 if (itn != mfs.end()) itn++;
836 while (itt != mfs.end()) {
837 if (!(itt->first.is_context_valid()))
840 if (itn != mfs.end()) itn++;
843 mf__key_ key(msh, o, qdim, complete);
844 mesh_fem_tab::iterator it = mfs.find(key);
845 assert(it == mfs.end() || it->second->is_context_valid());
847 if (it == mfs.end()) {
849 auto pmf = (p_torus_mesh) ? std::make_shared<torus_mesh_fem>(*p_torus_mesh, qdim)
850 : std::make_shared<mesh_fem>(msh, qdim);
851 pmf->set_classical_finite_element(o);
852 pmf->set_auto_add(o,
false);
853 return *(mfs[key] = pmf);
855 else return *(it->second);
861 dim_type order, dim_type qdim,
863 classical_mesh_fem_pool &pool
865 return pool(msh, order, qdim, complete);
868 struct dummy_mesh_fem_ {
870 dummy_mesh_fem_() : mf(dummy_mesh()) {}
877 void vectorize_base_tensor(
const base_tensor &t, base_matrix &vt,
879 GMM_ASSERT1(qdim == N || qdim == 1,
"mixed intrinsic vector and "
880 "tensorised fem is not supported");
881 gmm::resize(vt, ndof, N);
882 ndof = (ndof*qdim)/N;
885 gmm::copy(t.as_vector(), vt.as_vector());
886 }
else if (qdim == 1) {
888 base_tensor::const_iterator it = t.begin();
889 for (
size_type i = 0; i < ndof; ++i, ++it)
890 for (
size_type j = 0; j < N; ++j) vt(i*N+j, j) = *it;
894 void vectorize_grad_base_tensor(
const base_tensor &t, base_tensor &vt,
897 GMM_ASSERT1(qdim == Q || qdim == 1,
"mixed intrinsic vector and "
898 "tensorised fem is not supported");
899 vt.adjust_sizes(bgeot::multi_index(ndof, Q, N));
900 ndof = (ndof*qdim)/Q;
903 gmm::copy(t.as_vector(), vt.as_vector());
904 }
else if (qdim == 1) {
906 base_tensor::const_iterator it = t.begin();
908 for (
size_type i = 0; i < ndof; ++i, ++it)
909 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.