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