GetFEM  5.4.3
getfem_mesh_fem.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 1999-2020 Yves Renard
5 
6  This file is a part of GetFEM
7 
8  GetFEM is free software; you can redistribute it and/or modify it
9  under the terms of the GNU Lesser General Public License as published
10  by the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version along with the GCC Runtime Library
12  Exception either version 3.1 or (at your option) any later version.
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  License and GCC Runtime Library Exception for more details.
17  You should have received a copy of the GNU Lesser General Public License
18  along with this program; if not, write to the Free Software Foundation,
19  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 
21  As a special exception, you may use this file as it is a part of a free
22  software library without restriction. Specifically, if other files
23  instantiate templates or use macros or inline functions from this file,
24  or you compile this file and link it with other files to produce an
25  executable, this file does not by itself cause the resulting executable
26  to be covered by the GNU Lesser General Public License. This exception
27  does not however invalidate any other reasons why the executable file
28  might be covered by the GNU Lesser General Public License.
29 
30 ===========================================================================*/
31 
32 /**@file getfem_mesh_fem.h
33  @author Yves Renard <Yves.Renard@insa-lyon.fr>
34  @date December 21, 1999.
35  @brief Define the getfem::mesh_fem class
36 */
37 
38 #ifndef GETFEM_MESH_FEM_H__
39 #define GETFEM_MESH_FEM_H__
40 
41 #include "getfem_mesh.h"
42 #include "getfem_fem.h"
43 
44 
45 namespace getfem {
46 
47  template <class CONT> struct tab_scal_to_vect_iterator {
48 
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
54  difference_type;
55  typedef typename std::iterator_traits<ITER>::iterator_category
56  iterator_category;
57  typedef size_t size_type;
58  typedef tab_scal_to_vect_iterator<CONT> iterator;
59 
60  ITER it;
61  dim_type N;
62  dim_type ii;
63 
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; }
70 
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; }
75  iterator operator +(difference_type i) const
76  { iterator itt = *this; return (itt += i); }
77  iterator operator -(difference_type i) const
78  { iterator itt = *this; return (itt -= i); }
79  difference_type operator -(const iterator &i) const
80  { return (it - i.it) * N + ii - i.ii; }
81 
82  value_type operator *() const { return (*it) + ii; }
83  value_type operator [](int i) { return *(this + i); }
84 
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)); }
94 
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) { }
98 
99  };
100 
101  /** @internal @brief structure for iteration over the dofs when Qdim
102  != 1 and target_dim == 1
103  */
104  template <class CONT> class tab_scal_to_vect {
105  public :
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
113  difference_type;
114  typedef size_t size_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;
119 
120 
121  protected :
122  ITER it, ite;
123  dim_type N;
124 
125  public :
126 
127  bool empty() const { return it == ite; }
128  size_type size() const { return (ite - it) * N; }
129 
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()); }
136 
137  value_type front() const { return *begin(); }
138  value_type back() const { return *(--(end())); }
139 
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) {}
143 
144  value_type operator [](size_type ii) const { return *(begin() + ii);}
145  };
146 
147  /** Describe a finite element method linked to a mesh.
148  *
149  * @see mesh
150  * @see mesh_im
151  */
152  class mesh_fem : public context_dependencies, virtual public dal::static_stored_object {
153  protected :
154  typedef gmm::csc_matrix<scalar_type> REDUCTION_MATRIX;
155  typedef gmm::csr_matrix<scalar_type> EXTENSION_MATRIX;
156 
157  void copy_from(const mesh_fem &mf); /* Remember to change copy_from if
158  adding components to mesh_fem */
159 
160  std::vector<pfem> f_elems;
161  dal::bit_vector fe_convex;
162  const mesh *linked_mesh_;
163  REDUCTION_MATRIX R_;
164  EXTENSION_MATRIX E_;
165  mutable bgeot::mesh_structure dof_structure;
166  mutable bool dof_enumeration_made;
167  mutable bool is_uniform_, is_uniformly_vectorized_;
168  mutable size_type nb_total_dof;
169  pfem auto_add_elt_pf; /* fem for automatic addition */
170  /* of element option. (0 = no automatic addition) */
171  dim_type auto_add_elt_K; /* Degree of the fem for automatic addition */
172  /* of element option. (-1 = no automatic addition) */
173  bool auto_add_elt_disc, auto_add_elt_complete;
174  scalar_type auto_add_elt_alpha;
175  dim_type Qdim; /* this is the "total" target_dim. */
176  bgeot::multi_index mi; /* multi dimensions for matrix/tensor field. */
177  // dim_type QdimM, QdimN; /* for matrix field with QdimM lines and QdimN */
178  // /* columnsQdimM * QdimN = Qdim. */
179  std::vector<size_type> dof_partition;
180  mutable gmm::uint64_type v_num_update, v_num;
181  bool use_reduction; /* A reduction matrix is applied or not. */
182 
183  public :
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;
187 
188  void update_from_context() const;
189 
190  gmm::uint64_type version_number() const
191  { context_check(); return v_num; }
192 
193  /** Get the set of convexes where a finite element has been assigned.
194  */
195  inline const dal::bit_vector &convex_index() const
196  { context_check(); return fe_convex; }
197 
198  /// Return true if a reduction matrix is applied to the dofs.
199  bool is_reduced() const { return use_reduction; }
200 
201  /// Return the reduction matrix applied to the dofs.
202  const REDUCTION_MATRIX &reduction_matrix() const { return R_; }
203 
204  /// Return the extension matrix corresponding to reduction applied (RE=I).
205  const EXTENSION_MATRIX &extension_matrix() const { return E_; }
206 
207  /** Allows to set the reduction and the extension matrices.
208  * Should satify (RR*EE=I). */
209  template <typename MATR, typename MATE>
210  void set_reduction_matrices(const MATR &RR, const MATE &EE) {
211  context_check();
212  GMM_ASSERT1(gmm::mat_ncols(RR) == nb_basic_dof() &&
213  gmm::mat_nrows(EE) == nb_basic_dof() &&
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));
218  gmm::copy(RR, R_);
219  gmm::copy(EE, E_);
220  use_reduction = true;
221  touch(); v_num = act_counter();
222  }
223 
224  /** Allows to set the reduction and the extension matrices in order
225  * to keep only a certain number of dof. */
226  void reduce_to_basic_dof(const dal::bit_vector &kept_basic_dof);
227  void reduce_to_basic_dof(const std::set<size_type> &kept_basic_dof);
228 
229  /// Validate or invalidate the reduction (keeping the reduction matrices).
230  void set_reduction(bool r) {
231  if (r != use_reduction) {
232  use_reduction = r;
233  if (use_reduction) {
234  context_check();
235  GMM_ASSERT1(gmm::mat_ncols(R_) == nb_basic_dof() &&
236  gmm::mat_nrows(E_) == nb_basic_dof() &&
237  gmm::mat_nrows(R_) == gmm::mat_ncols(E_),
238  "Wrong dimension of reduction and/or extension matrices");
239  }
240  touch(); v_num = act_counter();
241  }
242  }
243 
244  template<typename VECT1, typename VECT2>
245  void reduce_vector(const VECT1 &V1, const VECT2 &V2) const {
246  if (is_reduced()) {
247  size_type qqdim = gmm::vect_size(V1) / nb_basic_dof();
248  if (qqdim == 1)
249  gmm::mult(reduction_matrix(), V1, const_cast<VECT2 &>(V2));
250  else
251  for (size_type k = 0; k < qqdim; ++k)
252  gmm::mult(reduction_matrix(),
253  gmm::sub_vector(V1, gmm::sub_slice(k, nb_basic_dof(),
254  qqdim)),
255  gmm::sub_vector(const_cast<VECT2 &>(V2),
256  gmm::sub_slice(k, nb_dof(),
257  qqdim)));
258  }
259  else gmm::copy(V1, const_cast<VECT2 &>(V2));
260  }
261 
262  template<typename VECT1, typename VECT2>
263  void extend_vector(const VECT1 &V1, const VECT2 &V2) const {
264  size_type nbd = nb_dof();
265  if (is_reduced() && nbd) {
266  size_type qqdim = gmm::vect_size(V1) / nbd;
267  if (qqdim == 1)
268  gmm::mult(extension_matrix(), V1, const_cast<VECT2 &>(V2));
269  else
270  for (size_type k = 0; k < qqdim; ++k)
271  gmm::mult(extension_matrix(),
272  gmm::sub_vector(V1, gmm::sub_slice(k, nb_dof(),
273  qqdim)),
274  gmm::sub_vector(const_cast<VECT2 &>(V2),
275  gmm::sub_slice(k, nb_basic_dof(),
276  qqdim)));
277  }
278  else gmm::copy(V1, const_cast<VECT2 &>(V2));
279  }
280 
281 
282  /// Return a reference to the underlying mesh.
283  const mesh &linked_mesh() const { return *linked_mesh_; }
284 
285  virtual bool is_uniform() const;
286  virtual bool is_uniformly_vectorized() const;
287 
288  /** Set the degree of the fem for automatic addition
289  * of element option. K=-1 disables the automatic addition.
290  */
291  void set_auto_add(dim_type K, bool disc = false,
292  scalar_type alpha = scalar_type(0),
293  bool complete=false) {
294  auto_add_elt_K = K;
295  auto_add_elt_disc = disc;
296  auto_add_elt_alpha = alpha;
297  auto_add_elt_complete = complete;
298  auto_add_elt_pf = 0;
299  }
300 
301  /** Set the fem for automatic addition
302  * of element option. pf=0 disables the automatic addition.
303  */
304  void set_auto_add(pfem pf) {
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;
310  }
311 
312  /** Return the Q dimension. A mesh_fem used for scalar fields has
313  Q=1, for vector fields, Q is typically equal to
314  linked_mesh().dim().
315  */
316  virtual dim_type get_qdim() const { return Qdim; }
317  virtual const bgeot::multi_index &get_qdims() const { return mi; }
318 
319  /** Change the Q dimension */
320  virtual void set_qdim(dim_type q) {
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();
324  }
325  }
326 
327  /** Set the dimension for a matrix field. */
328  virtual void set_qdim(dim_type M, dim_type N) {
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();
332  }
333  }
334 
335  /** Set the dimension for a fourth order tensor field. */
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
338  || mi[3] != P) {
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();
342  }
343  }
344 
345  /** Set the dimension for an arbitrary order tensor field. */
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))) {
351  mi = mii;
352  Qdim = dim_type(1);
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();
357  }
358  }
359 
360 
361  void set_qdim_mn(dim_type M, dim_type N) IS_DEPRECATED
362  { set_qdim(M,N); }
363 
364  /** for matrix fields, return the number of rows. */
365  dim_type get_qdim_m() const IS_DEPRECATED { return dim_type(mi[0]); }
366  /** for matrix fields, return the number of columns. */
367  dim_type get_qdim_n() const IS_DEPRECATED { return dim_type(mi[1]); }
368 
369 
370  /** Set the finite element method of a convex.
371  @param cv the convex number.
372  @param pf the finite element.
373  */
374  void set_finite_element(size_type cv, pfem pf);
375  /** Set the finite element on a set of convexes.
376  @param cvs the set of convex indexes, as a dal::bit_vector.
377  @param pf the finite element, typically obtained with
378  @code getfem::fem_descriptor("FEM_SOMETHING(..)")
379  @endcode
380  */
381  void set_finite_element(const dal::bit_vector &cvs, pfem pf);
382  /** shortcut for set_finite_element(linked_mesh().convex_index(),pf);
383  and set_auto_add(pf). */
384  void set_finite_element(pfem pf);
385  /** Set a classical (i.e. lagrange polynomial) finite element on
386  a convex.
387  @param cv is the convex number.
388  @param fem_degree the polynomial degree of the finite element.
389  @param complete is a flag for excluding incomplete element
390  irrespective of the element geometric transformation.
391  */
392  void set_classical_finite_element(size_type cv, dim_type fem_degree,
393  bool complete=false);
394  /** Set a classical (i.e. lagrange polynomial) finite element on
395  a set of convexes.
396  @param cvs the set of convexes, as a dal::bit_vector.
397  @param fem_degree the polynomial degree of the finite element.
398  */
399  void set_classical_finite_element(const dal::bit_vector &cvs,
400  dim_type fem_degree,
401  bool complete=false);
402  /** Similar to set_classical_finite_element, but uses
403  discontinuous lagrange elements.
404 
405  @param cv the convex index.
406  @param fem_degree the polynomial degree of the finite element.
407  @param alpha the node inset, 0 <= alpha < 1, where 0 implies
408  usual dof nodes, greater values move the nodes toward the
409  center of gravity, and 1 means that all degrees of freedom
410  collapse on the center of gravity.
411  */
413  dim_type fem_degree,
414  scalar_type alpha=0,
415  bool complete=false);
416  /** Similar to set_classical_finite_element, but uses
417  discontinuous lagrange elements.
418 
419  @param cvs the set of convexes, as a dal::bit_vector.
420  @param fem_degree the polynomial degree of the finite element.
421  @param alpha the node inset, 0 <= alpha < 1, where 0 implies
422  usual dof nodes, greater values move the nodes toward the
423  center of gravity, and 1 means that all degrees of freedom
424  collapse on the center of gravity.
425  */
426  void set_classical_discontinuous_finite_element(const dal::bit_vector &cvs,
427  dim_type fem_degree,
428  scalar_type alpha=0,
429  bool complete=false);
430  /** Shortcut for
431  * set_classical_finite_element(linked_mesh().convex_index(),...)
432  */
433  void set_classical_finite_element(dim_type fem_degree,
434  bool complete=false);
435  /** Shortcut for
436  * set_classical_discontinuous_finite_element(linked_mesh().convex_index()
437  * ,...)
438  */
439  void set_classical_discontinuous_finite_element(dim_type fem_degree,
440  scalar_type alpha=0,
441  bool complete=false);
442  /** Return the basic fem associated with an element (if no fem is
443  * associated, the function will crash! use the convex_index() of
444  * the mesh_fem to check that a fem is associated to a given
445  * convex). This fem does not take into account the optional
446  * vectorization due to qdim nor the optional reduction.
447  */
448  virtual pfem fem_of_element(size_type cv) const
449  { return ((cv < f_elems.size()) ? f_elems[cv] : 0); }
450  /** Give an array of the dof numbers a of convex.
451  * @param cv the convex number.
452  * @return a pseudo-container of the dof number.
453  */
454  virtual ind_dof_ct ind_basic_dof_of_element(size_type cv) const {
455  context_check(); if (!dof_enumeration_made) enumerate_dof();
456  return ind_dof_ct(dof_structure.ind_points_of_convex(cv),
457  dim_type(Qdim/fem_of_element(cv)->target_dim()));
458  }
459  ind_dof_ct ind_dof_of_element(size_type cv) const IS_DEPRECATED
460  { return ind_basic_dof_of_element(cv); }
461  virtual const std::vector<size_type> &
462  ind_scalar_basic_dof_of_element(size_type cv) const
463  { return dof_structure.ind_points_of_convex(cv); }
464  /** Give an array of the dof numbers lying of a convex face (all
465  degrees of freedom whose associated base function is non-zero
466  on the convex face).
467  @param cv the convex number.
468  @param f the face number.
469  @return a pseudo-container of the dof number.
470  */
471  virtual ind_dof_face_ct
473  context_check(); if (!dof_enumeration_made) enumerate_dof();
474  return ind_dof_face_ct
475  (dof_structure.ind_points_of_face_of_convex(cv, f),
476  dim_type(Qdim/fem_of_element(cv)->target_dim()));
477  }
478  ind_dof_face_ct
479  ind_dof_of_face_of_element(size_type cv,short_type f) const IS_DEPRECATED
480  { return ind_basic_dof_of_face_of_element(cv, f); }
481  /** Return the number of dof lying on the given convex face.
482  @param cv the convex number.
483  @param f the face number.
484  */
486  short_type f) const {
487  context_check(); if (!dof_enumeration_made) enumerate_dof();
488  pfem pf = f_elems[cv];
489  return dof_structure.structure_of_convex(cv)->nb_points_of_face(f)
490  * Qdim / pf->target_dim();
491  }
492  size_type nb_dof_of_face_of_element(size_type cv,
493  short_type f) const IS_DEPRECATED
494  { return nb_basic_dof_of_face_of_element(cv, f); }
495  /** Return the number of degrees of freedom attached to a given convex.
496  @param cv the convex number.
497  */
499  context_check(); if (!dof_enumeration_made) enumerate_dof();
500  pfem pf = f_elems[cv]; return pf->nb_dof(cv) * Qdim / pf->target_dim();
501  }
502  size_type nb_dof_of_element(size_type cv) const IS_DEPRECATED
503  { return nb_basic_dof_of_element(cv); }
504 
505  /* Return the geometrical location of a degree of freedom in the
506  reference convex.
507  @param cv the convex number.
508  @param i the local dof number.
509  const base_node &reference_point_of_dof(size_type cv,size_type i) const {
510  pfem pf = f_elems[cv];
511  return pf->node_of_dof(cv, i * pf->target_dim() / Qdim);
512  }
513  */
514  /** Return the geometrical location of a degree of freedom.
515  @param cv the convex number.
516  @param i the local dof number.
517  */
518  virtual base_node point_of_basic_dof(size_type cv, size_type i) const;
519  base_node point_of_dof(size_type cv, size_type i) const IS_DEPRECATED
520  { return point_of_basic_dof(cv, i); }
521  /** Return the geometrical location of a degree of freedom.
522  @param d the global dof number.
523  */
524  virtual base_node point_of_basic_dof(size_type d) const;
525  base_node point_of_dof(size_type d) const IS_DEPRECATED
526  { return point_of_basic_dof(d); }
527  /** Return the dof component number (0<= x <Qdim) */
528  virtual dim_type basic_dof_qdim(size_type d) const;
529  dim_type dof_qdim(size_type d) const IS_DEPRECATED
530  { return basic_dof_qdim(d); }
531  /** Shortcut for convex_to_dof(d)[0]
532  @param d the global dof number.
533  */
535  size_type first_convex_of_dof(size_type d) const IS_DEPRECATED
536  { return first_convex_of_basic_dof(d); }
537  /** Return the list of convexes attached to the specified dof
538  @param d the global dof number.
539  @return an array of convex numbers.
540  */
541  virtual const mesh::ind_cv_ct &convex_to_basic_dof(size_type d) const;
542  const mesh::ind_cv_ct &convex_to_dof(size_type d) const IS_DEPRECATED
543  { return convex_to_basic_dof(d); }
544 
545  /** Give an array that contains the global dof indices corresponding
546  * to the mesh_fem dofs or size_type(-1) if a dof is not global.
547  * @param ind the returned global dof indices array.
548  */
549  virtual void get_global_dof_index(std::vector<size_type> &ind) const;
550  /** Renumber the degrees of freedom. You should not have
551  * to call this function, as it is done automatically */
552  virtual void enumerate_dof() const;
553 
554 #if GETFEM_PARA_LEVEL > 1
555  void enumerate_dof_para()const;
556 #endif
557 
558  /** Return the total number of basic degrees of freedom (before the
559  * optional reduction). */
560  virtual size_type nb_basic_dof() const {
561  context_check();
562  if (!dof_enumeration_made) enumerate_dof();
563  return nb_total_dof;
564  }
565  /// Return the total number of degrees of freedom.
566  virtual size_type nb_dof() const {
567  context_check();
568  if (!dof_enumeration_made) enumerate_dof();
569  return use_reduction ? gmm::mat_nrows(R_) : nb_total_dof;
570  }
571  /** Get a list of basic dof lying on a given mesh_region.
572  @param b the mesh_region.
573  @return the list in a dal::bit_vector.
574  */
575  virtual dal::bit_vector basic_dof_on_region(const mesh_region &b) const;
576  /** Get a list of dof lying on a given mesh_region. For a reduced mesh_fem
577  a dof is lying on a region if its potential corresponding shape
578  function is nonzero on this region. The extension matrix is used
579  to make the correspondence between basic and reduced dofs.
580  @param b the mesh_region.
581  @return the list in a dal::bit_vector.
582  */
583  dal::bit_vector dof_on_region(const mesh_region &b) const;
584  dal::bit_vector dof_on_set(const mesh_region &b) const IS_DEPRECATED
585  { return dof_on_region(b); }
586 
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;
594  }
595  }
596  unsigned get_dof_partition(size_type cv) const {
597  return (cv < dof_partition.size() ? unsigned(dof_partition[cv]) : 0);
598  }
599  void clear_dof_partition() { dof_partition.clear(); }
600 
601  size_type memsize() const {
602  return dof_structure.memsize() +
603  sizeof(mesh_fem) - sizeof(bgeot::mesh_structure) +
604  f_elems.size() * sizeof(pfem) + fe_convex.memsize();
605  }
606  void init_with_mesh(const mesh &me, dim_type Q = 1);
607  /** Build a new mesh_fem. A mesh object must be supplied.
608  @param me the linked mesh.
609  @param Q the Q dimension (see mesh_fem::get_qdim).
610  */
611  explicit mesh_fem(const mesh &me, dim_type Q = 1);
612  mesh_fem();
613  mesh_fem(const mesh_fem &mf);
614  mesh_fem &operator=(const mesh_fem &mf);
615 
616  virtual ~mesh_fem();
617  virtual void clear();
618  /** Read the mesh_fem from a stream.
619  @param ist the stream.
620  */
621  virtual void read_from_file(std::istream &ist);
622  /** Read the mesh_fem from a file.
623  @param name the file name. */
624  void read_from_file(const std::string &name);
625  /* internal usage. */
626  void write_basic_to_file(std::ostream &ost) const;
627  /* internal usage. */
628  void write_reduction_matrices_to_file(std::ostream &ost) const;
629  /** Write the mesh_fem to a stream. */
630  virtual void write_to_file(std::ostream &ost) const;
631  /** Write the mesh_fem to a file.
632 
633  @param name the file name
634 
635  @param with_mesh if set, then the linked_mesh() will also be
636  saved to the file.
637  */
638  void write_to_file(const std::string &name, bool with_mesh=false) const;
639  };
640 
641  /** Gives the descriptor of a classical finite element method of degree K
642  on mesh.
643 
644  The mesh_fem won't be destroyed until its linked_mesh is
645  destroyed. All the mesh_fem built by this function are stored
646  in a cache, which means that calling this function twice with
647  the same arguments will return the same mesh_fem object. A
648  consequence is that you should NEVER modify this mesh_fem!
649  */
650  const mesh_fem &classical_mesh_fem(const mesh &mesh, dim_type degree,
651  dim_type qdim=1, bool complete=false);
652 
653  /** Dummy mesh_fem for default parameter of functions. */
654  const mesh_fem &dummy_mesh_fem();
655 
656 
657  /** Given a mesh_fem @param mf and a vector @param vec of size equal to
658  * mf.nb_basic_dof(), the output vector @param coeff will contain the
659  * values of @param vec corresponding to the basic dofs of element
660  * @param cv. The size of @param coeff is adjusted if necessary.
661  */
662  template <typename VEC1, typename VEC2>
664  const VEC1 &vec,
665  size_type cv, VEC2 &coeff,
666  size_type qmult1 = size_type(-1),
667  size_type qmult2 = size_type(-1)) {
668  if (qmult1 == size_type(-1)) {
669  size_type nbdof = mf.nb_basic_dof();
670  qmult1 = gmm::vect_size(vec) / nbdof;
671  GMM_ASSERT1(gmm::vect_size(vec) == qmult1 * nbdof, "Bad dof vector size");
672  }
673  if (qmult2 == size_type(-1)) {
674  qmult2 = mf.get_qdim();
675  if (qmult2 > 1) qmult2 /= mf.fem_of_element(cv)->target_dim();
676  }
677  size_type qmultot = qmult1*qmult2;
678  auto &ct = mf.ind_scalar_basic_dof_of_element(cv);
679  gmm::resize(coeff, ct.size()*qmultot);
680 
681  auto it = ct.begin();
682  auto itc = coeff.begin();
683  if (qmultot == 1) {
684  for (; it != ct.end(); ++it) *itc++ = vec[*it];
685  } else {
686  for (; it != ct.end(); ++it) {
687  auto itv = vec.begin()+(*it)*qmult1;
688  for (size_type m = 0; m < qmultot; ++m) *itc++ = *itv++;
689  }
690  }
691  }
692 
693  void vectorize_base_tensor(const base_tensor &t, base_matrix &vt,
694  size_type ndof, size_type qdim, size_type N);
695 
696  void vectorize_grad_base_tensor(const base_tensor &t, base_tensor &vt,
697  size_type ndof, size_type qdim, size_type N);
698 
699 
700 } /* end of namespace getfem. */
701 
702 
703 #endif /* GETFEM_MESH_FEM_H__ */
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: getfem_mesh.h:99
Definition of the finite element methods.
Define a getfem::getfem_mesh object.
void copy(const L1 &l1, L2 &l2)
*‍/
Definition: gmm_blas.h:978
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*‍/
Definition: gmm_blas.h:1664
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Definition: getfem_fem.h:244
gmm::uint16_type short_type
used as the common short type integer in the library
Definition: bgeot_config.h:73
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
Definition: bgeot_poly.h:756
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
Definition: bgeot_poly.h:749
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
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.