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