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) && (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_;
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;
186 gmm::uint64_type version_number()
const
205 template <
typename MATR,
typename MATE>
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();
227 if (r != use_reduction) {
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 {
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 {
262 size_type qqdim = gmm::vect_size(V1) / nbd;
268 gmm::sub_vector(V1, gmm::sub_slice(k,
nb_dof(),
270 gmm::sub_vector(
const_cast<VECT2 &
>(V2),
274 else gmm::copy(V1,
const_cast<VECT2 &
>(V2));
281 virtual bool is_uniform()
const;
282 virtual bool is_uniformly_vectorized()
const;
288 scalar_type alpha = scalar_type(0),
289 bool complete=
false) {
291 auto_add_elt_disc = disc;
292 auto_add_elt_alpha = alpha;
293 auto_add_elt_complete = complete;
301 auto_add_elt_pf = pf;
302 auto_add_elt_K = dim_type(-1);
303 auto_add_elt_disc =
false;
304 auto_add_elt_alpha = scalar_type(0);
305 auto_add_elt_complete =
false;
313 virtual const bgeot::multi_index &get_qdims()
const {
return mi; }
317 if (q != Qdim || mi.size() != 1) {
318 mi.resize(1); mi[0] = q; Qdim = q;
319 dof_enumeration_made =
false; touch(); v_num = act_counter();
325 if (mi.size() != 2 || mi[0] != M || mi[1] != N) {
326 mi.resize(2); mi[0] = M; mi[1] = N; Qdim = dim_type(M*N);
327 dof_enumeration_made =
false; touch(); v_num = act_counter();
332 virtual void set_qdim(dim_type M, dim_type N, dim_type O, dim_type P) {
333 if (mi.size() != 4 || mi[0] != M || mi[1] != N || mi[2] != O
335 mi.resize(4); mi[0] = M; mi[1] = N; mi[2] = O; mi[3] = P;
336 Qdim = dim_type(M*N*O*P);
337 dof_enumeration_made =
false; touch(); v_num = act_counter();
342 virtual void set_qdim(
const bgeot::multi_index &mii) {
343 GMM_ASSERT1(mii.size() < 7,
344 "Tensor field are taken into account up to order 6.");
345 GMM_ASSERT1(mi.size(),
"Wrong sizes");
346 if (!(mi.is_equal(mii))) {
349 for (
size_type i = 0; i < mi.size(); ++i)
350 Qdim = dim_type(Qdim*mi[i]);
351 GMM_ASSERT1(Qdim,
"Wrong sizes");
352 dof_enumeration_made =
false; touch(); v_num = act_counter();
357 void set_qdim_mn(dim_type M, dim_type N) IS_DEPRECATED
361 dim_type
get_qdim_m() const IS_DEPRECATED {
return dim_type(mi[0]); }
363 dim_type
get_qdim_n() const IS_DEPRECATED {
return dim_type(mi[1]); }
389 bool complete=
false);
397 bool complete=
false);
411 bool complete=
false);
425 bool complete=
false);
430 bool complete=
false);
437 bool complete=
false);
445 {
return ((cv < f_elems.size()) ? f_elems[cv] : 0); }
455 ind_dof_ct ind_dof_of_element(
size_type cv)
const IS_DEPRECATED
457 virtual const std::vector<size_type> &
458 ind_scalar_basic_dof_of_element(
size_type cv)
const
467 virtual ind_dof_face_ct
470 return ind_dof_face_ct
484 pfem pf = f_elems[cv];
486 * Qdim / pf->target_dim();
496 pfem pf = f_elems[cv];
return pf->nb_dof(cv) * Qdim / pf->target_dim();
521 base_node point_of_dof(
size_type d)
const IS_DEPRECATED
525 dim_type dof_qdim(
size_type d)
const IS_DEPRECATED
538 const mesh::ind_cv_ct &convex_to_dof(
size_type d)
const IS_DEPRECATED
550 #if GETFEM_PARA_LEVEL > 1
551 void enumerate_dof_para()
const;
565 return use_reduction ? gmm::mat_nrows(R_) : nb_total_dof;
580 dal::bit_vector dof_on_set(
const mesh_region &b)
const IS_DEPRECATED
583 void set_dof_partition(
size_type cv,
unsigned partition_num) {
584 if (dof_partition.empty() && partition_num == 0)
return;
585 if (dof_partition.size() <
linked_mesh().nb_allocated_convex())
586 dof_partition.resize(
linked_mesh().nb_allocated_convex());
587 if (dof_partition.at(cv) != partition_num) {
588 dof_partition[cv] = partition_num;
589 dof_enumeration_made =
false;
592 unsigned get_dof_partition(
size_type cv)
const {
593 return (cv < dof_partition.size() ?
unsigned(dof_partition[cv]) : 0);
595 void clear_dof_partition() { dof_partition.clear(); }
598 return dof_structure.memsize() +
600 f_elems.size() *
sizeof(
pfem) + fe_convex.memsize();
602 void init_with_mesh(
const mesh &me, dim_type Q = 1);
607 explicit mesh_fem(
const mesh &me, dim_type Q = 1);
610 mesh_fem &operator=(
const mesh_fem &mf);
613 virtual void clear();
622 void write_basic_to_file(std::ostream &ost)
const;
624 void write_reduction_matrices_to_file(std::ostream &ost)
const;
634 void write_to_file(
const std::string &name,
bool with_mesh=
false)
const;
647 dim_type qdim=1,
bool complete=
false);
658 template <
typename VEC1,
typename VEC2>
666 qmult1 = gmm::vect_size(vec) / nbdof;
667 GMM_ASSERT1(gmm::vect_size(vec) == qmult1 * nbdof,
"Bad dof vector size");
674 auto &ct = mf.ind_scalar_basic_dof_of_element(cv);
675 gmm::resize(coeff, ct.size()*qmultot);
677 auto it = ct.begin();
678 auto itc = coeff.begin();
680 for (; it != ct.end(); ++it) *itc++ = vec[*it];
682 for (; it != ct.end(); ++it) {
683 auto itv = vec.begin()+(*it)*qmult1;
684 for (
size_type m = 0; m < qmultot; ++m) *itc++ = *itv++;
689 void vectorize_base_tensor(
const base_tensor &t, base_matrix &vt,
692 void vectorize_grad_base_tensor(
const base_tensor &t, base_tensor &vt,