38 #ifndef GETFEM_MESH_FEM_H__ 
   39 #define GETFEM_MESH_FEM_H__ 
   47   template <
class CONT> 
struct tab_scal_to_vect_iterator {
 
   49     typedef typename CONT::const_iterator ITER;
 
   50     typedef typename std::iterator_traits<ITER>::value_type value_type;
 
   51     typedef typename std::iterator_traits<ITER>::pointer    pointer;
 
   52     typedef typename std::iterator_traits<ITER>::reference  reference;
 
   53     typedef typename std::iterator_traits<ITER>::difference_type
 
   55     typedef typename std::iterator_traits<ITER>::iterator_category
 
   58     typedef tab_scal_to_vect_iterator<CONT> iterator;
 
   64     iterator &operator ++()
 
   65     { ++ii; 
if (ii == N) { ii = 0; ++it; } 
return *
this; }
 
   66     iterator &operator --()
 
   67     { 
if (ii == 0) { ii = N; --it; } --ii; 
return *
this; }
 
   68     iterator operator ++(
int) { iterator tmp = *
this; ++(*this); 
return tmp; }
 
   69     iterator operator --(
int) { iterator tmp = *
this; --(*this); 
return tmp; }
 
   71     iterator &operator +=(difference_type i)
 
   72     { it += (i+ii)/N; ii = dim_type((ii + i) % N); 
return *
this; }
 
   73     iterator &operator -=(difference_type i)
 
   74     { it -= (i+N-ii-1)/N; ii = (ii - i + N * i) % N; 
return *
this; }
 
   76     { iterator itt = *
this; 
return (itt += i); }
 
   78     { iterator itt = *
this; 
return (itt -= i); }
 
   79     difference_type 
operator -(
const iterator &i)
 const 
   80     { 
return (it - i.it) * N + ii - i.ii; }
 
   82     value_type operator *()
 const { 
return (*it) + ii; }
 
   83     value_type operator [](
int i) { 
return *(
this + i); }
 
   85     bool operator ==(
const iterator &i)
 const 
   86     { 
return (it == i.it) && (ii == i.ii); }
 
   87     bool operator !=(
const iterator &i)
 const { 
return !(i == *
this); }
 
   88     bool operator < (
const iterator &i)
 const 
   89     { 
return (it < i.it) || ((it == i.it) && (ii < i.ii)); }
 
   90     bool operator > (
const iterator &i)
 const 
   91     { 
return (it > i.it) || ((it == i.it) && (ii > i.ii)); }
 
   92     bool operator >= (
const iterator &i)
 const 
   93     { 
return (it > i.it) || ((it == i.it) && (ii >= i.ii)); }
 
   95     tab_scal_to_vect_iterator() {}
 
   96     tab_scal_to_vect_iterator(
const ITER &iter, dim_type n, dim_type i)
 
   97       : it(iter), N(n), ii(i) { }
 
  104   template <
class CONT> 
class tab_scal_to_vect {
 
  106     typedef typename CONT::const_iterator ITER;
 
  107     typedef typename std::iterator_traits<ITER>::value_type value_type;
 
  108     typedef typename std::iterator_traits<ITER>::pointer    pointer;
 
  109     typedef typename std::iterator_traits<ITER>::pointer    const_pointer;
 
  110     typedef typename std::iterator_traits<ITER>::reference  reference;
 
  111     typedef typename std::iterator_traits<ITER>::reference  const_reference;
 
  112     typedef typename std::iterator_traits<ITER>::difference_type
 
  115     typedef tab_scal_to_vect_iterator<CONT> iterator;
 
  116     typedef iterator                          const_iterator;
 
  117     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
  118     typedef std::reverse_iterator<iterator> reverse_iterator;
 
  127     bool empty()
 const { 
return it == ite; }
 
  128     size_type size()
 const { 
return (ite - it) * N; }
 
  130     const_iterator begin()
 const { 
return iterator(it, N, 0); }
 
  131     const_iterator end()
 const { 
return iterator(ite, N, 0); }
 
  132     const_reverse_iterator rbegin()
 const 
  133     { 
return const_reverse_iterator(end()); }
 
  134     const_reverse_iterator rend()
 const 
  135     { 
return const_reverse_iterator(begin()); }
 
  137     value_type front()
 const { 
return *begin(); }
 
  138     value_type back()
 const { 
return *(--(end())); }
 
  140     tab_scal_to_vect() : N(0) {}
 
  141     tab_scal_to_vect(
const CONT &cc, dim_type n)
 
  142       : it(cc.begin()), ite(cc.end()), N(n) {}
 
  144     value_type operator [](
size_type ii)
 const { 
return *(begin() + ii);}
 
  154     typedef gmm::csc_matrix<scalar_type> REDUCTION_MATRIX;
 
  155     typedef gmm::csr_matrix<scalar_type> EXTENSION_MATRIX;
 
  160     std::vector<pfem> f_elems;
 
  161     dal::bit_vector fe_convex;
 
  162     const mesh *linked_mesh_;
 
  166     mutable bool dof_enumeration_made;
 
  167     mutable bool is_uniform_, is_uniformly_vectorized_;
 
  169     pfem auto_add_elt_pf; 
 
  171     dim_type auto_add_elt_K; 
 
  173     bool auto_add_elt_disc, auto_add_elt_complete;
 
  174     scalar_type auto_add_elt_alpha;
 
  176     bgeot::multi_index mi; 
 
  179     std::vector<size_type> dof_partition;
 
  180     mutable gmm::uint64_type v_num_update, v_num;
 
  184     typedef base_node point_type;
 
  185     typedef tab_scal_to_vect<mesh::ind_cv_ct> ind_dof_ct;
 
  186     typedef tab_scal_to_vect<mesh::ind_pt_face_ct> ind_dof_face_ct;
 
  190     gmm::uint64_type version_number()
 const 
  209     template <
typename MATR, 
typename MATE>
 
  214                   gmm::mat_nrows(RR) == gmm::mat_ncols(EE),
 
  215                   "Wrong dimension of reduction and/or extension matrices");
 
  216       R_ = REDUCTION_MATRIX(gmm::mat_nrows(RR), gmm::mat_ncols(RR));
 
  217       E_ = EXTENSION_MATRIX(gmm::mat_nrows(EE), gmm::mat_ncols(EE));
 
  220       use_reduction = 
true;
 
  221       touch(); v_num = act_counter();
 
  231       if (r != use_reduction) {
 
  237                       gmm::mat_nrows(R_) == gmm::mat_ncols(E_),
 
  238                     "Wrong dimension of reduction and/or extension matrices");
 
  240         touch(); v_num = act_counter();
 
  244     template<
typename VECT1, 
typename VECT2>
 
  245     void reduce_vector(
const VECT1 &V1, 
const VECT2 &V2)
 const {
 
  255                       gmm::sub_vector(
const_cast<VECT2 &
>(V2),
 
  256                                       gmm::sub_slice(k, 
nb_dof(),
 
  259       else gmm::copy(V1, 
const_cast<VECT2 &
>(V2));
 
  262     template<
typename VECT1, 
typename VECT2>
 
  263     void extend_vector(
const VECT1 &V1, 
const VECT2 &V2)
 const {
 
  266         size_type qqdim = gmm::vect_size(V1) / nbd;
 
  272                       gmm::sub_vector(V1, gmm::sub_slice(k, 
nb_dof(),
 
  274                       gmm::sub_vector(
const_cast<VECT2 &
>(V2),
 
  278       else gmm::copy(V1, 
const_cast<VECT2 &
>(V2));
 
  285     virtual bool is_uniform() 
const;
 
  286     virtual bool is_uniformly_vectorized() 
const;
 
  292                       scalar_type alpha = scalar_type(0),
 
  293                       bool complete=
false) {
 
  295       auto_add_elt_disc = disc;
 
  296       auto_add_elt_alpha = alpha;
 
  297       auto_add_elt_complete = complete;
 
  305       auto_add_elt_pf = pf;
 
  306       auto_add_elt_K = dim_type(-1);
 
  307       auto_add_elt_disc = 
false;
 
  308       auto_add_elt_alpha = scalar_type(0);
 
  309       auto_add_elt_complete = 
false;
 
  317     virtual const bgeot::multi_index &get_qdims()
 const { 
return mi; }
 
  321       if (q != Qdim || mi.size() != 1) {
 
  322         mi.resize(1); mi[0] = q; Qdim = q;
 
  323         dof_enumeration_made = 
false; touch(); v_num = act_counter();
 
  329       if (mi.size() != 2 || mi[0] != M || mi[1] != N) {
 
  330         mi.resize(2); mi[0] = M; mi[1] = N; Qdim = dim_type(M*N);
 
  331         dof_enumeration_made = 
false; touch(); v_num = act_counter();
 
  336     virtual void set_qdim(dim_type M, dim_type N, dim_type O, dim_type P) {
 
  337       if (mi.size() != 4 || mi[0] != M || mi[1] != N || mi[2] != O
 
  339         mi.resize(4); mi[0] = M; mi[1] = N; mi[2] = O; mi[3] = P;
 
  340         Qdim = dim_type(M*N*O*P);
 
  341         dof_enumeration_made = 
false; touch(); v_num = act_counter();
 
  346     virtual void set_qdim(
const bgeot::multi_index &mii) {
 
  347       GMM_ASSERT1(mii.size() < 7,
 
  348                   "Tensor field are taken into account up to order 6.");
 
  349       GMM_ASSERT1(mi.size(), 
"Wrong sizes");
 
  350       if (!(mi.is_equal(mii))) {
 
  353         for (
size_type i = 0; i < mi.size(); ++i)
 
  354           Qdim = dim_type(Qdim*mi[i]);
 
  355         GMM_ASSERT1(Qdim, 
"Wrong sizes");
 
  356         dof_enumeration_made = 
false; touch(); v_num = act_counter();
 
  361     void set_qdim_mn(dim_type M, dim_type N) IS_DEPRECATED
 
  365     dim_type 
get_qdim_m() const IS_DEPRECATED { 
return dim_type(mi[0]); }
 
  367     dim_type 
get_qdim_n() const IS_DEPRECATED { 
return dim_type(mi[1]); }
 
  393                                       bool complete=
false);
 
  401                                       bool complete=
false);
 
  415                                                     bool complete=
false);
 
  429                                                     bool complete=
false);
 
  434                                       bool complete=
false);
 
  441                                                     bool complete=
false);
 
  449     { 
return ((cv < f_elems.size()) ? f_elems[cv] : 0); }
 
  459     ind_dof_ct ind_dof_of_element(
size_type cv) 
const IS_DEPRECATED
 
  461     virtual const std::vector<size_type> &
 
  462     ind_scalar_basic_dof_of_element(
size_type cv)
 const 
  471     virtual ind_dof_face_ct
 
  474       return ind_dof_face_ct
 
  488       pfem pf = f_elems[cv];
 
  490         * Qdim / pf->target_dim();
 
  500       pfem pf = f_elems[cv]; 
return pf->nb_dof(cv) * Qdim / pf->target_dim();
 
  525     base_node point_of_dof(
size_type d) 
const IS_DEPRECATED
 
  529     dim_type dof_qdim(
size_type d) 
const IS_DEPRECATED
 
  542     const mesh::ind_cv_ct &convex_to_dof(
size_type d) 
const IS_DEPRECATED
 
  554 #if GETFEM_PARA_LEVEL > 1 
  555     void enumerate_dof_para()
const;
 
  569       return use_reduction ? gmm::mat_nrows(R_) : nb_total_dof;
 
  584     dal::bit_vector dof_on_set(
const mesh_region &b) 
const IS_DEPRECATED
 
  587     void set_dof_partition(
size_type cv, 
unsigned partition_num) {
 
  588       if (dof_partition.empty() && partition_num == 0) 
return;
 
  589       if (dof_partition.size() < 
linked_mesh().nb_allocated_convex())
 
  590         dof_partition.resize(
linked_mesh().nb_allocated_convex());
 
  591       if (dof_partition.at(cv) != partition_num) {
 
  592         dof_partition[cv] = partition_num;
 
  593         dof_enumeration_made = 
false;
 
  596     unsigned get_dof_partition(
size_type cv)
 const {
 
  597       return (cv < dof_partition.size() ? 
unsigned(dof_partition[cv]) : 0);
 
  599     void clear_dof_partition() { dof_partition.clear(); }
 
  602       return dof_structure.memsize() +
 
  604         f_elems.size() * 
sizeof(
pfem) + fe_convex.memsize();
 
  606     void init_with_mesh(
const mesh &me, dim_type Q = 1);
 
  611     explicit mesh_fem(
const mesh &me, dim_type Q = 1);
 
  614     mesh_fem &operator=(
const mesh_fem &mf);
 
  617     virtual void clear();
 
  626     void write_basic_to_file(std::ostream &ost) 
const;
 
  628     void write_reduction_matrices_to_file(std::ostream &ost) 
const;
 
  638     void write_to_file(
const std::string &name, 
bool with_mesh=
false) 
const;
 
  651                                      dim_type qdim=1, 
bool complete=
false);
 
  662   template <
typename VEC1, 
typename VEC2>
 
  670       qmult1 = gmm::vect_size(vec) / nbdof;
 
  671       GMM_ASSERT1(gmm::vect_size(vec) == qmult1 * nbdof, 
"Bad dof vector size");
 
  678     auto &ct = mf.ind_scalar_basic_dof_of_element(cv);
 
  679     gmm::resize(coeff, ct.size()*qmultot);
 
  681     auto it = ct.begin();
 
  682     auto itc = coeff.begin();
 
  684       for (; it != ct.end(); ++it) *itc++ = vec[*it];
 
  686       for (; it != ct.end(); ++it) {
 
  687         auto itv = vec.begin()+(*it)*qmult1;
 
  688         for (
size_type m = 0; m < qmultot; ++m) *itc++ = *itv++;
 
  693   void vectorize_base_tensor(
const base_tensor &t, base_matrix &vt,
 
  696   void vectorize_grad_base_tensor(
const base_tensor &t, base_tensor &vt,
 
Mesh structure definition.
 
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.
 
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
 
const ind_set & ind_points_of_convex(size_type ic) const
Return a container to the list of points attached to convex ic.
 
base class for static stored objects
 
Deal with interdependencies of objects.
 
bool context_check() const
return true if update_from_context was called
 
Describe a finite element method linked to a mesh.
 
void set_auto_add(pfem pf)
Set the fem for automatic addition of element option.
 
dim_type get_qdim_n() const IS_DEPRECATED
for matrix fields, return the number of columns.
 
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 void set_qdim(dim_type M, dim_type N, dim_type O, dim_type P)
Set the dimension for a fourth order tensor field.
 
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 void set_qdim(const bgeot::multi_index &mii)
Set the dimension for an arbitrary order tensor field.
 
dim_type get_qdim_m() const IS_DEPRECATED
for matrix fields, return the number of rows.
 
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.
 
virtual void set_qdim(dim_type M, dim_type N)
Set the dimension for a matrix field.
 
mesh_fem(const mesh &me, dim_type Q=1)
Build a new mesh_fem.
 
void update_from_context() const
this function has to be defined and should update the object when the context is modified.
 
const EXTENSION_MATRIX & extension_matrix() const
Return the extension matrix corresponding to reduction applied (RE=I).
 
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.
 
const REDUCTION_MATRIX & reduction_matrix() const
Return the reduction matrix applied to the dofs.
 
virtual ind_dof_face_ct ind_basic_dof_of_face_of_element(size_type cv, short_type f) const
Give an array of the dof numbers lying of a convex face (all degrees of freedom whose associated base...
 
void set_reduction(bool r)
Validate or invalidate the reduction (keeping the reduction matrices).
 
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 size_type nb_basic_dof_of_face_of_element(size_type cv, short_type f) const
Return the number of dof lying on the given convex face.
 
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.
 
structure used to hold a set of convexes and/or convex faces.
 
Describe a mesh (collection of convexes (elements) and points).
 
Definition of the finite element methods.
 
Define a getfem::getfem_mesh object.
 
void copy(const L1 &l1, L2 &l2)
*/
 
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
 
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
 
gmm::uint16_type short_type
used as the common short type integer in the library
 
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
 
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
 
size_t size_type
used as the common size type in the library
 
GEneric Tool for Finite Element Methods.
 
const mesh_fem & dummy_mesh_fem()
Dummy mesh_fem for default parameter of functions.
 
void slice_vector_on_basic_dof_of_element(const mesh_fem &mf, const VEC1 &vec, size_type cv, VEC2 &coeff, size_type qmult1=size_type(-1), size_type qmult2=size_type(-1))
Given a mesh_fem.
 
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.