136 #ifndef GETFEM_FEM_H__ 
  137 #define GETFEM_FEM_H__ 
  160   struct dof_description;
 
  247   typedef std::shared_ptr<const getfem::virtual_fem> 
pfem;
 
  250   typedef std::shared_ptr<const getfem::fem_precomp_> pfem_precomp;
 
  256                       public std::enable_shared_from_this<const virtual_fem> {
 
  258     enum vec_type { VECTORIAL_NOTRANSFORM_TYPE, VECTORIAL_PRIMAL_TYPE,
 
  259                     VECTORIAL_DUAL_TYPE };
 
  263     mutable std::vector<pdof_description> dof_types_;
 
  269     std::shared_ptr<bgeot::convex_structure> cvs_node;
 
  270     std::vector<std::vector<short_type>> face_tab; 
 
  272     mutable bgeot::pstored_point_tab pspt;
 
  273     mutable bool pspt_valid;
 
  274     bgeot::pconvex_ref cvr; 
 
  275     dim_type ntarget_dim;   
 
  276     mutable dim_type dim_;  
 
  281     bool real_element_defined;
 
  282     bool is_standard_fem;   
 
  287     std::string debug_name_;
 
  297     { 
return dof_types_.size(); }
 
  303       { 
return nb_base(cv) * ntarget_dim; }
 
  305       { 
return nb_dof(cv) * ntarget_dim; }
 
  308       { 
return dof_types_; }
 
  309     short_type hierarchical_raff()
 const { 
return hier_raff; }
 
  311     dim_type 
dim()
 const { 
return dim_; }
 
  312     dim_type &
dim() { 
return dim_; }
 
  320     bgeot::pconvex_ref &mref_convex() { 
return cvr; }
 
  330     const std::string &debug_name()
 const { 
return debug_name_; }
 
  331     std::string &debug_name() { 
return debug_name_; }
 
  332     virtual bgeot::pstored_point_tab node_tab(
size_type)
 const {
 
  334         pspt = bgeot::store_point_tab(cv_node.points());
 
  346       { 
return (*(node_tab(cv)))[i];}
 
  347     virtual const std::vector<short_type> &
 
  349     bool is_on_real_element()
 const { 
return real_element_defined; }
 
  350     bool is_equivalent()
 const { 
return is_equiv; }
 
  352     { 
return !(is_equivalent()) || real_element_defined; }
 
  357     bool is_polynomialcomp()
 const { 
return is_polycomp; }
 
  358     bool is_standard()
 const { 
return is_standard_fem; }
 
  359     bool &is_polynomialcomp() { 
return is_polycomp; }
 
  360     bool &is_equivalent() { 
return is_equiv; }
 
  363     bool &is_standard() { 
return is_standard_fem; }
 
  364     short_type estimated_degree()
 const { 
return es_degree; }
 
  365     short_type &estimated_degree() { 
return es_degree; }
 
  367     virtual void mat_trans(base_matrix &, 
const base_matrix &,
 
  369     { GMM_ASSERT1(
false, 
"This function should not be called."); }
 
  385     template<
typename CVEC, 
typename VVEC>
 
  387                        const CVEC& coeff, VVEC &val, dim_type Qdim) 
const;
 
  395     template <
typename MAT>
 
  397                        MAT &M, dim_type Qdim) 
const;
 
  402     template<
typename CVEC, 
typename VMAT>
 
  404                             const CVEC& coeff, VMAT &val,
 
  405                             dim_type Qdim=1) 
const;
 
  410     template<
typename CVEC, 
typename VMAT>
 
  412                             const CVEC& coeff, VMAT &val,
 
  413                             dim_type Qdim) 
const;
 
  418     template<
typename CVEC>
 
  420       (
const fem_interpolation_context& c, 
const CVEC& coeff,
 
  421        typename gmm::linalg_traits<CVEC>::value_type &val) 
const;
 
  427     virtual void base_value(
const base_node &x, base_tensor &t) 
const = 0;
 
  447                                  base_tensor &t, 
bool withM = 
true) 
const;
 
  455                                       base_tensor &t, 
bool withM = 
true) 
const;
 
  463                                       base_tensor &t, 
bool withM = 
true) 
const;
 
  466       { GMM_ASSERT1(
false, 
"internal error."); }
 
  473                   const dal::bit_vector &faces);
 
  475     void init_cvs_node();
 
  476     void unfreeze_cvs_node();
 
  479       copy(f); 
return *
this;
 
  483       DAL_STORED_OBJECT_DEBUG_CREATED(
this, 
"Fem");
 
  484       ntarget_dim = 1; dim_ = 1;
 
  485       is_equiv = is_pol = is_polycomp = is_lag = is_standard_fem = 
false;
 
  486       pspt_valid = 
false; hier_raff = 0; real_element_defined = 
false;
 
  488       vtype = VECTORIAL_NOTRANSFORM_TYPE;
 
  489       cvs_node = bgeot::new_convex_structure();
 
  491     virtual_fem(
const virtual_fem& f)
 
  492       : 
dal::static_stored_object(),
 
  493         std::enable_shared_from_this<const virtual_fem>()
 
  494     { copy(f); DAL_STORED_OBJECT_DEBUG_CREATED(
this, 
"Fem"); }
 
  495     virtual ~virtual_fem() { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this, 
"Fem"); }
 
  497     void copy(
const virtual_fem &f);
 
  507     std::vector<FUNC> base_;
 
  508     mutable std::vector<std::vector<FUNC>> grad_, hess_;
 
  509     mutable bool grad_computed_ = 
false;
 
  510     mutable bool hess_computed_ = 
false;
 
  512     void compute_grad_()
 const {
 
  513       if (grad_computed_) 
return;
 
  515       if (grad_computed_) 
return;
 
  521         for (dim_type j = 0; j < n; ++j) {
 
  522           grad_[i][j] = base_[i]; grad_[i][j].derivative(j);
 
  525       grad_computed_ = 
true;
 
  528     void compute_hess_()
 const {
 
  529       if (hess_computed_) 
return;
 
  531       if (hess_computed_) 
return;
 
  536         hess_[i].resize(n*n);
 
  537         for (dim_type j = 0; j < n; ++j) {
 
  538           for (dim_type k = 0; k < n; ++k) {
 
  539             hess_[i][j+k*n] = base_[i];
 
  540             hess_[i][j+k*n].derivative(j); hess_[i][j+k*n].derivative(k);
 
  544       hess_computed_ = 
true;
 
  550     const std::vector<FUNC> &
base()
 const { 
return base_; }
 
  551     std::vector<FUNC> &
base() { 
return base_; }
 
  555       bgeot::multi_index mi(2);
 
  559       base_tensor::iterator it = t.begin();
 
  561         *it = bgeot::to_scalar(base_[i].eval(x.begin()));
 
  567       if (!grad_computed_) compute_grad_();
 
  568       bgeot::multi_index mi(3);
 
  573       base_tensor::iterator it = t.begin();
 
  574       for (dim_type j = 0; j < n; ++j)
 
  576           *it = bgeot::to_scalar(grad_[i][j].eval(x.begin()));
 
  582       if (!hess_computed_) compute_hess_();
 
  583       bgeot::multi_index mi(4);
 
  589       base_tensor::iterator it = t.begin();
 
  590       for (dim_type k = 0; k < n; ++k)
 
  591         for (dim_type j = 0; j < n; ++j)
 
  593             *it = bgeot::to_scalar(hess_[i][j+k*n].eval(x.begin()));
 
  616                      bool complete=
false);
 
  637                                    scalar_type alpha=0, 
bool complete=
false);
 
  657     const bgeot::pstored_point_tab pspt;
 
  658     mutable std::vector<base_tensor> c;   
 
  659     mutable std::vector<base_tensor> pc;  
 
  660     mutable std::vector<base_tensor> hpc; 
 
  664       { 
if (c.empty()) init_val(); 
return c[i]; }
 
  667       { 
if (pc.empty()) init_grad(); 
return pc[i]; }
 
  670       { 
if (hpc.empty()) init_hess(); 
return hpc[i]; }
 
  671     inline pfem get_pfem()
 const { 
return pf; }
 
  674     inline bgeot::pstored_point_tab get_ppoint_tab()
 const 
  676     fem_precomp_(
const pfem, 
const bgeot::pstored_point_tab);
 
  677     ~fem_precomp_() { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this, 
"Fem_precomp"); }
 
  679     void init_val() 
const;
 
  680     void init_grad() 
const;
 
  681     void init_hess() 
const;
 
  703                            dal::pstatic_stored_object dep);
 
  718     std::set<pfem_precomp> precomps;
 
  752     mutable base_matrix M_; 
 
  764     const base_matrix& 
M() 
const;
 
  768     void base_value(base_tensor& t, 
bool withM = 
true) 
const;
 
  770     void pfp_base_value(base_tensor& t, 
const pfem_precomp &pfp__);
 
  776     void pfp_grad_base_value(base_tensor& t, 
const pfem_precomp &pfp__);
 
  785     bool is_convex_num_valid() 
const;
 
  786     void invalid_convex_num() { convex_num_ = 
size_type(-1); }
 
  794     pfem_precomp 
pfp()
 const { 
return pfp_; }
 
  795     void set_pfp(pfem_precomp newpfp);
 
  796     void set_pf(
pfem newpf);
 
  797     int xfem_side()
 const { 
return xfem_side_; }
 
  798     void set_xfem_side(
int side) { xfem_side_ = side; }
 
  799     void change(bgeot::pgeotrans_precomp pgp__,
 
  801                 const base_matrix& G__, 
size_type convex_num__,
 
  803       bgeot::geotrans_interpolation_context::change(pgp__,ii__,G__);
 
  804       convex_num_ = convex_num__; face_num_ = face_num__;  xfem_side_ = 0;
 
  809                 const base_matrix& G__, 
size_type convex_num__,
 
  811       bgeot::geotrans_interpolation_context::change
 
  812         (pgt__, pfp__->get_ppoint_tab(), ii__, G__);
 
  813       convex_num_ = convex_num__; face_num_ = face_num__; xfem_side_ = 0;
 
  817                 pfem pf__, 
const base_node& xref__, 
const base_matrix& G__,
 
  819       bgeot::geotrans_interpolation_context::change(pgt__,xref__,G__);
 
  820       pf_ = pf__; pfp_ = 0; convex_num_ = convex_num__; face_num_ = face_num__;
 
  823     fem_interpolation_context()
 
  824       : 
bgeot::geotrans_interpolation_context(),
 
  826     fem_interpolation_context(bgeot::pgeotrans_precomp pgp__,
 
  828                               const base_matrix& G__,
 
  831       : 
bgeot::geotrans_interpolation_context(pgp__,ii__,G__),
 
  832         convex_num_(convex_num__), face_num_(face_num__), xfem_side_(0)
 
  836                               const base_matrix& G__,
 
  839       : 
bgeot::geotrans_interpolation_context(pgt__,pfp__->get_ppoint_tab(),
 
  841         convex_num_(convex_num__), face_num_(face_num__), xfem_side_(0)
 
  845                               const base_node& xref__,
 
  846                               const base_matrix& G__,
 
  849       : 
bgeot::geotrans_interpolation_context(pgt__,xref__,G__),
 
  850         pf_(pf__), pfp_(0), convex_num_(convex_num__), face_num_(face_num__),
 
  857   template <
typename CVEC, 
typename VVEC>
 
  859                                   const CVEC& coeff, VVEC &val,
 
  860                                   dim_type Qdim)
 const {
 
  863     GMM_ASSERT1(gmm::vect_size(val) == Qdim, 
"dimensions mismatch");
 
  864     GMM_ASSERT1(gmm::vect_size(coeff) == nbdof*Qmult,
 
  865                 "Wrong size for coeff vector");
 
  872         typename gmm::linalg_traits<CVEC>::value_type co = coeff[j*Qmult+q];
 
  874           val[r + q*
target_dim()] += co * Z[j + r*nbdof];
 
  879   template <
typename MAT>
 
  881                                   MAT &M, dim_type Qdim)
 const {
 
  884     GMM_ASSERT1(gmm::mat_nrows(M) == Qdim && gmm::mat_ncols(M) == nbdof*Qmult,
 
  885                 "dimensions mismatch");
 
  892           M(r+q*
target_dim(), j*Qmult+q) = Z[j + r*nbdof];
 
  901   template<
typename CVEC, 
typename VMAT>
 
  903                                        const CVEC& coeff, VMAT &val,
 
  904                                        dim_type Qdim)
 const {
 
  907     size_type Qmult = gmm::vect_size(coeff) / nbdof;
 
  908     GMM_ASSERT1(gmm::mat_ncols(val) == N &&
 
  910                 gmm::vect_size(coeff) == nbdof*Qmult,
 
  911                 "dimensions mismatch");
 
  913                 "dimensions mismatch");
 
  919       base_tensor::const_iterator it = t.begin();
 
  922           for (
size_type j = 0; j < nbdof; ++j, ++it)
 
  923             val(r + q*
target_dim(), k) += coeff[j*Qmult+q] * (*it);
 
  928   template<
typename CVEC, 
typename VMAT>
 
  930                                        const CVEC& coeff, VMAT &val,
 
  931                                        dim_type Qdim)
 const {
 
  934     GMM_ASSERT1(gmm::mat_ncols(val) == N*N &&
 
  935                 gmm::mat_nrows(val) == Qdim, 
"dimensions mismatch");
 
  943       base_tensor::const_iterator it = t.begin();
 
  946           for (
size_type j = 0; j < nbdof; ++j, ++it)
 
  947             val(r + q*
target_dim(), k) += coeff[j*Qmult+q] * (*it);
 
  955   template<
typename CVEC>
 
  958      typename gmm::linalg_traits<CVEC>::value_type &val)
 const {
 
  961     size_type Qmult = gmm::vect_size(coeff) / nbdof;
 
  962     GMM_ASSERT1(gmm::vect_size(coeff) == nbdof*Qmult , 
"dimensions mismatch");
 
  965                 "Dimensions mismatch. Divergence operator requires fem qdim equal to dim.");
 
  971     val = scalar_type(0);
 
  972     base_tensor::const_iterator it = t.begin();
 
  975         if (k) it += (N*nbdof + 1);
 
  978           val += coeff[j] * (*it);
 
  986           val += coeff[j*N+k] * (*it);
 
 1001   typedef dal::naming_system<virtual_fem>::param_list fem_param_list;
 
 1006   void add_fem_name(std::string name,
 
Geometric transformations on convexes.
 
Handle composite polynomials.
 
the geotrans_interpolation_context structure is passed as the argument of geometric transformation in...
 
Associate a name to a method descriptor and store method descriptors.
 
base class for static stored objects
 
structure passed as the argument of fem interpolation functions.
 
Pre-computations on a fem (given a fixed set of points on the reference convex, this object computes ...
 
virtual_fem implementation as a vector of generic functions.
 
Base class for finite element description.
 
Stores interdependent getfem objects.
 
Integration methods (exact and approximated) on convexes.
 
pdof_description derivative_dof(dim_type d, dim_type r)
Description of a unique dof of derivative type.
 
int dof_description_compare(pdof_description a, pdof_description b)
Gives a total order on the dof description compatible with the identification.
 
pdof_description second_derivative_dof(dim_type d, dim_type num_der1, dim_type num_der2)
Description of a unique dof of second derivative type.
 
pdof_description mean_value_dof(dim_type d)
Description of a unique dof of mean value type.
 
bool dof_linkable(pdof_description)
Says if the dof is linkable.
 
bool dof_compatibility(pdof_description, pdof_description)
Says if the two dofs can be identified.
 
pdof_description xfem_dof(pdof_description p, size_type ind)
Description of a special dof for Xfem.
 
pdof_description lagrange_dof(dim_type d)
Description of a unique dof of lagrange type (value at the node).
 
size_type dof_xfem_index(pdof_description)
Returns the xfem_index of dof (0 for normal dof)
 
pdof_description global_dof(dim_type d)
Description of a global dof, i.e.
 
pdof_description normal_derivative_dof(dim_type d)
Description of a unique dof of normal derivative type (normal derivative at the node,...
 
dof_description * pdof_description
Type representing a pointer on a dof_description.
 
pdof_description product_dof(pdof_description pnd1, pdof_description pnd2)
Product description of the descriptions *pnd1 and *pnd2.
 
void hess_base_value(const base_node &x, base_tensor &t) const
Evaluates at point x, the hessian of all base functions w.r.t.
 
bool is_lagrange() const
true if the base functions are such that
 
void add_node(const pdof_description &d, const base_node &pt, const dal::bit_vector &faces)
internal function adding a node to an element for the creation of a finite element method.
 
virtual void hess_base_value(const base_node &x, base_tensor &t) const =0
Give the value of all hessians (on ref.
 
virtual void real_hess_base_value(const fem_interpolation_context &c, base_tensor &t, bool withM=true) const
Give the hessian of all components of the base functions at the current point of the fem_interpolatio...
 
dim_type target_dim() const
dimension of the target space.
 
size_type convex_num() const
get the current convex number
 
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
 
virtual void real_grad_base_value(const fem_interpolation_context &c, base_tensor &t, bool withM=true) const
Give the gradient of all components of the base functions at the current point of the fem_interpolati...
 
void delete_fem_precomp(pfem_precomp pfp)
Request for the removal of a pfem_precomp.
 
const fem< bgeot::base_rational_fraction > * prationalfracfem
Rational fration FEM.
 
const base_node & node_of_dof(size_type cv, size_type i) const
Gives the node corresponding to the dof i.
 
void grad_base_value(const base_node &x, base_tensor &t) const
Evaluates at point x, the gradient of all base functions w.r.t.
 
vec_type vectorial_type() const
Type of vectorial element.
 
bool have_pfp() const
true if a fem_precomp_ has been supplied.
 
void base_value(const base_node &x, base_tensor &t) const
Evaluates at point x, all base functions and returns the result in t(nb_base,target_dim)
 
const base_matrix & M() const
non tau-equivalent transformation matrix.
 
void interpolation_diverg(const fem_interpolation_context &c, const CVEC &coeff, typename gmm::linalg_traits< CVEC >::value_type &val) const
Interpolation of the divergence.
 
void interpolation_hess(const fem_interpolation_context &c, const CVEC &coeff, VMAT &val, dim_type Qdim) const
Interpolation of the hessian.
 
virtual size_type nb_base(size_type cv) const
Number of basis functions.
 
const fem< bgeot::polynomial_composite > * ppolycompfem
Polynomial composite FEM.
 
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
 
const base_tensor & grad(size_type i) const
returns gradients of the base functions
 
void hess_base_value(base_tensor &t, bool withM=true) const
fill the tensor with the hessian of the base functions (taken at point this->xref())
 
bool have_pf() const
true if the pfem is available.
 
pfem classical_discontinuous_fem(bgeot::pgeometric_trans pg, short_type k, scalar_type alpha=0, bool complete=false)
Give a pointer on the structures describing the classical polynomial discontinuous fem of degree k on...
 
bgeot::pconvex_structure structure(size_type cv) const
Gives the convex structure of the reference element nodes.
 
void grad_base_value(base_tensor &t, bool withM=true) const
fill the tensor with the gradient of the base functions (taken at point this->xref())
 
pfem classical_fem(bgeot::pgeometric_trans pgt, short_type k, bool complete=false)
Give a pointer on the structures describing the classical polynomial fem of degree k on a given conve...
 
void base_value(base_tensor &t, bool withM=true) const
fill the tensor with the values of the base functions (taken at point this->xref())
 
short_type face_num() const
get the current face number
 
bgeot::pconvex_structure basic_structure(size_type cv) const
Gives the convex of the reference element.
 
const std::vector< pdof_description > & dof_types() const
Get the array of pointer on dof description.
 
virtual const bgeot::convex< base_node > & node_convex(size_type) const
Gives the convex representing the nodes on the reference element.
 
void interpolation(const fem_interpolation_context &c, const CVEC &coeff, VVEC &val, dim_type Qdim) const
Interpolate at an arbitrary point x given on the reference element.
 
void interpolation_grad(const fem_interpolation_context &c, const CVEC &coeff, VMAT &val, dim_type Qdim=1) const
Interpolation of the gradient.
 
const std::vector< FUNC > & base() const
Gives the array of basic functions (components).
 
pfem interior_fem_of_hho_method(pfem hho_method)
Specific function for a HHO method to obtain the method in the interior.
 
bool is_polynomial() const
true if the base functions are polynomials
 
const pfem pf() const
get the current FEM descriptor
 
virtual void base_value(const base_node &x, base_tensor &t) const =0
Give the value of all components of the base functions at the point x of the reference element.
 
pfem_precomp fem_precomp(pfem pf, bgeot::pstored_point_tab pspt, dal::pstatic_stored_object dep)
Handles precomputations for FEM.
 
size_type nb_base_components(size_type cv) const
Number of components (nb_dof() * dimension of the target space).
 
void set_face_num(short_type f)
set the current face number
 
virtual void grad_base_value(const base_node &x, base_tensor &t) const =0
Give the value of all gradients (on ref.
 
bool is_on_face() const
On a face ?
 
pfem_precomp pfp() const
get the current fem_precomp_
 
pfem_precomp operator()(pfem pf, bgeot::pstored_point_tab pspt)
Request a pfem_precomp.
 
dim_type dim() const
dimension of the reference element.
 
virtual bgeot::pconvex_ref ref_convex(size_type) const
Return the convex of the reference element.
 
const base_tensor & val(size_type i) const
returns values of the base functions
 
const fem< bgeot::base_poly > * ppolyfem
Classical polynomial FEM.
 
virtual size_type nb_dof(size_type) const
Number of degrees of freedom.
 
virtual void real_base_value(const fem_interpolation_context &c, base_tensor &t, bool withM=true) const
Give the value of all components of the base functions at the current point of the fem_interpolation_...
 
const base_tensor & hess(size_type i) const
returns hessians of the base functions
 
std::string name_of_fem(pfem p)
get the string name of a fem descriptor.
 
gmm::uint16_type short_type
used as the common short type integer in the library
 
base_poly read_base_poly(short_type n, std::istream &f)
read a base_poly on the stream ist.
 
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
 
size_t size_type
used as the common size type in the library
 
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
 
void del_stored_object(const pstatic_stored_object &o, bool ignore_unstored)
Delete an object and the object which depend on it.
 
GEneric Tool for Finite Element Methods.