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-1; --it; }
else --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) && (ii < i.ii); }
91 tab_scal_to_vect_iterator() {}
92 tab_scal_to_vect_iterator(
const ITER &iter, dim_type n, dim_type i)
93 : it(iter), N(n), ii(i) { }
100 template <
class CONT>
class tab_scal_to_vect {
102 typedef typename CONT::const_iterator ITER;
103 typedef typename std::iterator_traits<ITER>::value_type value_type;
104 typedef typename std::iterator_traits<ITER>::pointer pointer;
105 typedef typename std::iterator_traits<ITER>::pointer const_pointer;
106 typedef typename std::iterator_traits<ITER>::reference reference;
107 typedef typename std::iterator_traits<ITER>::reference const_reference;
108 typedef typename std::iterator_traits<ITER>::difference_type
111 typedef tab_scal_to_vect_iterator<CONT> iterator;
112 typedef iterator const_iterator;
113 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
114 typedef std::reverse_iterator<iterator> reverse_iterator;
123 bool empty()
const {
return it == ite; }
124 size_type size()
const {
return (ite - it) * N; }
126 const_iterator begin()
const {
return iterator(it, N, 0); }
127 const_iterator end()
const {
return iterator(ite, N, 0); }
128 const_reverse_iterator rbegin()
const 129 {
return const_reverse_iterator(end()); }
130 const_reverse_iterator rend()
const 131 {
return const_reverse_iterator(begin()); }
133 value_type front()
const {
return *begin(); }
134 value_type back()
const {
return *(--(end())); }
136 tab_scal_to_vect() : N(0) {}
137 tab_scal_to_vect(
const CONT &cc, dim_type n)
138 : it(cc.begin()), ite(cc.end()), N(n) {}
140 value_type operator [](size_type ii)
const {
return *(begin() + ii);}
150 typedef gmm::csc_matrix<scalar_type> REDUCTION_MATRIX;
151 typedef gmm::csr_matrix<scalar_type> EXTENSION_MATRIX;
156 std::vector<pfem> f_elems;
157 dal::bit_vector fe_convex;
158 const mesh *linked_mesh_;
162 mutable bool dof_enumeration_made;
163 mutable bool is_uniform_, is_uniformly_vectorized_;
164 mutable size_type nb_total_dof;
165 pfem auto_add_elt_pf;
167 dim_type auto_add_elt_K;
169 bool auto_add_elt_disc, auto_add_elt_complete;
170 scalar_type auto_add_elt_alpha;
172 bgeot::multi_index mi;
175 std::vector<size_type> dof_partition;
176 mutable gmm::uint64_type v_num_update, v_num;
180 typedef base_node point_type;
181 typedef tab_scal_to_vect<mesh::ind_cv_ct> ind_dof_ct;
182 typedef tab_scal_to_vect<mesh::ind_pt_face_ct> ind_dof_face_ct;
184 void update_from_context()
const;
186 gmm::uint64_type version_number()
const 187 { context_check();
return v_num; }
192 { context_check();
return fe_convex; }
205 template <
typename MATR,
typename MATE>
208 GMM_ASSERT1(gmm::mat_ncols(RR) == nb_basic_dof() &&
209 gmm::mat_nrows(EE) == nb_basic_dof() &&
210 gmm::mat_nrows(RR) == gmm::mat_ncols(EE),
211 "Wrong dimension of reduction and/or extension matrices");
212 R_ = REDUCTION_MATRIX(gmm::mat_nrows(RR), gmm::mat_ncols(RR));
213 E_ = EXTENSION_MATRIX(gmm::mat_nrows(EE), gmm::mat_ncols(EE));
216 use_reduction =
true;
217 touch(); v_num = act_counter();
222 void reduce_to_basic_dof(
const dal::bit_vector &kept_basic_dof);
223 void reduce_to_basic_dof(
const std::set<size_type> &kept_basic_dof);
227 if (r != use_reduction) {
231 GMM_ASSERT1(gmm::mat_ncols(R_) == nb_basic_dof() &&
232 gmm::mat_nrows(E_) == nb_basic_dof() &&
233 gmm::mat_nrows(R_) == gmm::mat_ncols(E_),
234 "Wrong dimension of reduction and/or extension matrices");
236 touch(); v_num = act_counter();
240 template<
typename VECT1,
typename VECT2>
241 void reduce_vector(
const VECT1 &V1,
const VECT2 &V2)
const {
243 size_type qqdim = gmm::vect_size(V1) / nb_basic_dof();
245 gmm::mult(reduction_matrix(), V1, const_cast<VECT2 &>(V2));
247 for (size_type k = 0; k < qqdim; ++k)
248 gmm::mult(reduction_matrix(),
249 gmm::sub_vector(V1, gmm::sub_slice(k, nb_basic_dof(),
251 gmm::sub_vector(const_cast<VECT2 &>(V2),
252 gmm::sub_slice(k, nb_dof(),
255 else gmm::copy(V1, const_cast<VECT2 &>(V2));
258 template<
typename VECT1,
typename VECT2>
259 void extend_vector(
const VECT1 &V1,
const VECT2 &V2)
const {
261 size_type qqdim = gmm::vect_size(V1) / nb_dof();
263 gmm::mult(extension_matrix(), V1, const_cast<VECT2 &>(V2));
265 for (size_type k = 0; k < qqdim; ++k)
266 gmm::mult(extension_matrix(),
267 gmm::sub_vector(V1, gmm::sub_slice(k, nb_dof(),
269 gmm::sub_vector(const_cast<VECT2 &>(V2),
270 gmm::sub_slice(k, nb_basic_dof(),
273 else gmm::copy(V1, const_cast<VECT2 &>(V2));
280 virtual bool is_uniform()
const;
281 virtual bool is_uniformly_vectorized()
const;
287 scalar_type alpha = scalar_type(0),
288 bool complete=
false) {
290 auto_add_elt_disc = disc;
291 auto_add_elt_alpha = alpha;
292 auto_add_elt_complete = complete;
300 auto_add_elt_pf = pf;
301 auto_add_elt_K = dim_type(-1);
302 auto_add_elt_disc =
false;
303 auto_add_elt_alpha = scalar_type(0);
304 auto_add_elt_complete =
false;
312 virtual const bgeot::multi_index &get_qdims()
const {
return mi; }
316 if (q != Qdim || mi.size() != 1) {
317 mi.resize(1); mi[0] = q; Qdim = q;
318 dof_enumeration_made =
false; touch(); v_num = act_counter();
324 if (mi.size() != 2 || mi[0] != M || mi[1] != N) {
325 mi.resize(2); mi[0] = M; mi[1] = N; Qdim = dim_type(M*N);
326 dof_enumeration_made =
false; touch(); v_num = act_counter();
331 virtual void set_qdim(dim_type M, dim_type N, dim_type O, dim_type P) {
332 if (mi.size() != 4 || mi[0] != M || mi[1] != N || mi[2] != O
334 mi.resize(4); mi[0] = M; mi[1] = N; mi[2] = O; mi[3] = P;
335 Qdim = dim_type(M*N*O*P);
336 dof_enumeration_made =
false; touch(); v_num = act_counter();
341 virtual void set_qdim(
const bgeot::multi_index &mii) {
342 GMM_ASSERT1(mii.size() < 7,
343 "Tensor field are taken into account up to order 6.");
344 GMM_ASSERT1(mi.size(),
"Wrong sizes");
345 if (!(mi.is_equal(mii))) {
348 for (size_type i = 0; i < mi.size(); ++i)
349 Qdim = dim_type(Qdim*mi[i]);
350 GMM_ASSERT1(Qdim,
"Wrong sizes");
351 dof_enumeration_made =
false; touch(); v_num = act_counter();
356 void set_qdim_mn(dim_type M, dim_type N) IS_DEPRECATED
360 dim_type
get_qdim_m() const IS_DEPRECATED {
return dim_type(mi[0]); }
362 dim_type
get_qdim_n() const IS_DEPRECATED {
return dim_type(mi[1]); }
369 void set_finite_element(size_type cv,
pfem pf);
376 void set_finite_element(
const dal::bit_vector &cvs,
pfem pf);
379 void set_finite_element(
pfem pf);
387 void set_classical_finite_element(size_type cv, dim_type fem_degree,
388 bool complete=
false);
394 void set_classical_finite_element(
const dal::bit_vector &cvs,
396 bool complete=
false);
407 void set_classical_discontinuous_finite_element(size_type cv,
410 bool complete=
false);
421 void set_classical_discontinuous_finite_element(
const dal::bit_vector &cvs,
424 bool complete=
false);
428 void set_classical_finite_element(dim_type fem_degree,
429 bool complete=
false);
434 void set_classical_discontinuous_finite_element(dim_type fem_degree,
436 bool complete=
false);
444 {
return ((cv < f_elems.size()) ? f_elems[cv] : 0); }
450 context_check();
if (!dof_enumeration_made) enumerate_dof();
452 dim_type(Qdim/fem_of_element(cv)->target_dim()));
454 ind_dof_ct ind_dof_of_element(size_type cv)
const IS_DEPRECATED
455 {
return ind_basic_dof_of_element(cv); }
456 virtual const bgeot::mesh_structure::ind_cv_ct &
457 ind_scalar_basic_dof_of_element(size_type cv)
const 466 virtual ind_dof_face_ct
468 context_check();
if (!dof_enumeration_made) enumerate_dof();
469 return ind_dof_face_ct
471 dim_type(Qdim/fem_of_element(cv)->target_dim()));
474 ind_dof_of_face_of_element(size_type cv,
short_type f)
const IS_DEPRECATED
475 {
return ind_basic_dof_of_face_of_element(cv, f); }
482 context_check();
if (!dof_enumeration_made) enumerate_dof();
483 pfem pf = f_elems[cv];
485 * Qdim / pf->target_dim();
487 size_type nb_dof_of_face_of_element(size_type cv,
489 {
return nb_basic_dof_of_face_of_element(cv, f); }
494 context_check();
if (!dof_enumeration_made) enumerate_dof();
495 pfem pf = f_elems[cv];
return pf->nb_dof(cv) * Qdim / pf->target_dim();
497 size_type nb_dof_of_element(size_type cv)
const IS_DEPRECATED
498 {
return nb_basic_dof_of_element(cv); }
513 virtual base_node point_of_basic_dof(size_type cv, size_type i)
const;
514 base_node point_of_dof(size_type cv, size_type i)
const IS_DEPRECATED
515 {
return point_of_basic_dof(cv, i); }
519 virtual base_node point_of_basic_dof(size_type d)
const;
520 base_node point_of_dof(size_type d)
const IS_DEPRECATED
521 {
return point_of_basic_dof(d); }
523 virtual dim_type basic_dof_qdim(size_type d)
const;
524 dim_type dof_qdim(size_type d)
const IS_DEPRECATED
525 {
return basic_dof_qdim(d); }
529 virtual size_type first_convex_of_basic_dof(size_type d)
const;
530 size_type first_convex_of_dof(size_type d)
const IS_DEPRECATED
531 {
return first_convex_of_basic_dof(d); }
536 virtual const mesh::ind_cv_ct &convex_to_basic_dof(size_type d)
const;
537 const mesh::ind_cv_ct &convex_to_dof(size_type d)
const IS_DEPRECATED
538 {
return convex_to_basic_dof(d); }
544 virtual void get_global_dof_index(std::vector<size_type> &ind)
const;
547 virtual void enumerate_dof()
const;
549 #if GETFEM_PARA_LEVEL > 1 550 void enumerate_dof_para()
const;
556 context_check();
if (!dof_enumeration_made) enumerate_dof();
561 context_check();
if (!dof_enumeration_made) enumerate_dof();
562 return use_reduction ? gmm::mat_nrows(R_) : nb_total_dof;
568 virtual dal::bit_vector basic_dof_on_region(
const mesh_region &b)
const;
576 dal::bit_vector dof_on_region(
const mesh_region &b)
const;
577 dal::bit_vector dof_on_set(
const mesh_region &b)
const IS_DEPRECATED
578 {
return dof_on_region(b); }
580 void set_dof_partition(size_type cv,
unsigned partition_num) {
581 if (dof_partition.empty() && partition_num == 0)
return;
582 if (dof_partition.size() < linked_mesh().nb_allocated_convex())
583 dof_partition.resize(linked_mesh().nb_allocated_convex());
584 if (dof_partition.at(cv) != partition_num) {
585 dof_partition[cv] = partition_num;
586 dof_enumeration_made =
false;
589 unsigned get_dof_partition(size_type cv)
const {
590 return (cv < dof_partition.size() ? unsigned(dof_partition[cv]) : 0);
592 void clear_dof_partition() { dof_partition.clear(); }
594 size_type memsize()
const {
595 return dof_structure.memsize() +
597 f_elems.size() *
sizeof(
pfem) + fe_convex.memsize();
599 void init_with_mesh(
const mesh &me, dim_type Q = 1);
610 virtual void clear();
614 virtual void read_from_file(std::istream &ist);
617 void read_from_file(
const std::string &name);
619 void write_basic_to_file(std::ostream &ost)
const;
621 void write_reduction_matrices_to_file(std::ostream &ost)
const;
623 virtual void write_to_file(std::ostream &ost)
const;
631 void write_to_file(
const std::string &name,
bool with_mesh=
false)
const;
644 dim_type qdim=1,
bool complete=
false);
655 template <
typename VEC1,
typename VEC2>
658 size_type cv, VEC2 &coeff,
663 qmult1 = gmm::vect_size(vec) / nbdof;
664 GMM_ASSERT1(gmm::vect_size(vec) == qmult1 * nbdof,
"Bad dof vector size");
670 size_type qmultot = qmult1*qmult2;
671 auto &ct = mf.ind_scalar_basic_dof_of_element(cv);
672 gmm::resize(coeff, ct.size()*qmultot);
674 auto it = ct.begin();
675 auto itc = coeff.begin();
677 for (; it != ct.end(); ++it) *itc++ = vec[*it];
679 for (; it != ct.end(); ++it) {
680 auto itv = vec.begin()+(*it)*qmult1;
681 for (size_type m = 0; m < qmultot; ++m) *itc++ = *itv++;
686 void vectorize_base_tensor(
const base_tensor &t, base_matrix &vt,
687 size_type ndof, size_type qdim, size_type N);
689 void vectorize_grad_base_tensor(
const base_tensor &t, base_tensor &vt,
690 size_type ndof, size_type qdim, size_type N);
virtual size_type nb_basic_dof_of_element(size_type cv) const
Return the number of degrees of freedom attached to a given convex.
dim_type get_qdim_n() const IS_DEPRECATED
for matrix fields, return the number of columns.
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
structure used to hold a set of convexes and/or convex faces.
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.
Define a getfem::getfem_mesh object.
base class for static stored objects
const mesh_fem & dummy_mesh_fem()
Dummy mesh_fem for default parameter of functions.
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.
void set_reduction_matrices(const MATR &RR, const MATE &EE)
Allows to set the reduction and the extension matrices.
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.
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 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! us...
Describe a mesh (collection of convexes (elements) and points).
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
const REDUCTION_MATRIX & reduction_matrix() const
Return the reduction matrix applied to the dofs.
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
const EXTENSION_MATRIX & extension_matrix() const
Return the extension matrix corresponding to reduction applied (RE=I).
size_t size_type
used as the common size type in the library
virtual size_type nb_basic_dof() const
Return the total number of basic degrees of freedom (before the optional reduction).
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 dim_type get_qdim() const
Return the Q dimension.
bool is_reduced() const
Return true if a reduction matrix is applied to the dofs.
Deal with interdependencies of objects.
GEneric Tool for Finite Element Methods.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Describe a finite element method linked to a mesh.
gmm::uint16_type short_type
used as the common short type integer in the library
void set_auto_add(pfem pf)
Set the fem for automatic addition of element option.
Mesh structure definition.
Definition of the finite element methods.
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...
virtual void set_qdim(dim_type M, dim_type N)
Set the dimension for a matrix field.
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
const ind_cv_ct & ind_points_of_convex(size_type ic) const
Return a container to the list of points attached to convex ic.
const dal::bit_vector & convex_index() const
Get the set of convexes where a finite element has been assigned.
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 ind_dof_ct ind_basic_dof_of_element(size_type cv) const
Give an array of the dof numbers a of convex.
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.
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.