135 #ifndef GETFEM_FEM_H__
136 #define GETFEM_FEM_H__
159 struct dof_description;
246 typedef std::shared_ptr<const getfem::virtual_fem>
pfem;
249 typedef std::shared_ptr<const getfem::fem_precomp_> pfem_precomp;
255 public std::enable_shared_from_this<const virtual_fem> {
257 enum vec_type { VECTORIAL_NOTRANSFORM_TYPE, VECTORIAL_PRIMAL_TYPE,
258 VECTORIAL_DUAL_TYPE };
262 mutable std::vector<pdof_description> dof_types_;
268 std::shared_ptr<bgeot::convex_structure> cvs_node;
269 std::vector<std::vector<short_type>> face_tab;
271 mutable bgeot::pstored_point_tab pspt;
272 mutable bool pspt_valid;
273 bgeot::pconvex_ref cvr;
274 dim_type ntarget_dim;
275 mutable dim_type dim_;
280 bool real_element_defined;
281 bool is_standard_fem;
286 std::string debug_name_;
296 {
return dof_types_.size(); }
302 {
return nb_base(cv) * ntarget_dim; }
304 {
return nb_dof(cv) * ntarget_dim; }
307 {
return dof_types_; }
308 short_type hierarchical_raff()
const {
return hier_raff; }
310 dim_type
dim()
const {
return dim_; }
311 dim_type &
dim() {
return dim_; }
319 bgeot::pconvex_ref &mref_convex() {
return cvr; }
329 const std::string &debug_name()
const {
return debug_name_; }
330 std::string &debug_name() {
return debug_name_; }
331 virtual bgeot::pstored_point_tab node_tab(
size_type)
const {
333 pspt = bgeot::store_point_tab(cv_node.points());
345 {
return (*(node_tab(cv)))[i];}
346 virtual const std::vector<short_type> &
348 bool is_on_real_element()
const {
return real_element_defined; }
349 bool is_equivalent()
const {
return is_equiv; }
351 {
return !(is_equivalent()) || real_element_defined; }
356 bool is_polynomialcomp()
const {
return is_polycomp; }
357 bool is_standard()
const {
return is_standard_fem; }
358 bool &is_polynomialcomp() {
return is_polycomp; }
359 bool &is_equivalent() {
return is_equiv; }
362 bool &is_standard() {
return is_standard_fem; }
363 short_type estimated_degree()
const {
return es_degree; }
364 short_type &estimated_degree() {
return es_degree; }
366 virtual void mat_trans(base_matrix &,
const base_matrix &,
368 { GMM_ASSERT1(
false,
"This function should not be called."); }
384 template<
typename CVEC,
typename VVEC>
386 const CVEC& coeff, VVEC &val, dim_type Qdim)
const;
394 template <
typename MAT>
396 MAT &M, dim_type Qdim)
const;
401 template<
typename CVEC,
typename VMAT>
403 const CVEC& coeff, VMAT &val,
404 dim_type Qdim=1)
const;
409 template<
typename CVEC,
typename VMAT>
411 const CVEC& coeff, VMAT &val,
412 dim_type Qdim)
const;
417 template<
typename CVEC>
419 (
const fem_interpolation_context& c,
const CVEC& coeff,
420 typename gmm::linalg_traits<CVEC>::value_type &val)
const;
426 virtual void base_value(
const base_node &x, base_tensor &t)
const = 0;
446 base_tensor &t,
bool withM =
true)
const;
454 base_tensor &t,
bool withM =
true)
const;
462 base_tensor &t,
bool withM =
true)
const;
465 { GMM_ASSERT1(
false,
"internal error."); }
472 const dal::bit_vector &faces);
474 void init_cvs_node();
475 void unfreeze_cvs_node();
478 copy(f);
return *
this;
482 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"Fem");
483 ntarget_dim = 1; dim_ = 1;
484 is_equiv = is_pol = is_polycomp = is_lag = is_standard_fem =
false;
485 pspt_valid =
false; hier_raff = 0; real_element_defined =
false;
487 vtype = VECTORIAL_NOTRANSFORM_TYPE;
488 cvs_node = bgeot::new_convex_structure();
490 virtual_fem(
const virtual_fem& f)
491 :
dal::static_stored_object(),
492 std::enable_shared_from_this<const virtual_fem>()
493 { copy(f); DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"Fem"); }
494 virtual ~virtual_fem() { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this,
"Fem"); }
496 void copy(
const virtual_fem &f);
506 std::vector<FUNC> base_;
507 mutable std::vector<std::vector<FUNC>> grad_, hess_;
508 mutable bool grad_computed_ =
false;
509 mutable bool hess_computed_ =
false;
511 void compute_grad_()
const {
512 if (grad_computed_)
return;
514 if (grad_computed_)
return;
520 for (dim_type j = 0; j < n; ++j) {
521 grad_[i][j] = base_[i]; grad_[i][j].derivative(j);
524 grad_computed_ =
true;
527 void compute_hess_()
const {
528 if (hess_computed_)
return;
530 if (hess_computed_)
return;
535 hess_[i].resize(n*n);
536 for (dim_type j = 0; j < n; ++j) {
537 for (dim_type k = 0; k < n; ++k) {
538 hess_[i][j+k*n] = base_[i];
539 hess_[i][j+k*n].derivative(j); hess_[i][j+k*n].derivative(k);
543 hess_computed_ =
true;
549 const std::vector<FUNC> &
base()
const {
return base_; }
550 std::vector<FUNC> &
base() {
return base_; }
554 bgeot::multi_index mi(2);
558 base_tensor::iterator it = t.begin();
560 *it = bgeot::to_scalar(base_[i].eval(x.begin()));
566 if (!grad_computed_) compute_grad_();
567 bgeot::multi_index mi(3);
572 base_tensor::iterator it = t.begin();
573 for (dim_type j = 0; j < n; ++j)
575 *it = bgeot::to_scalar(grad_[i][j].eval(x.begin()));
581 if (!hess_computed_) compute_hess_();
582 bgeot::multi_index mi(4);
588 base_tensor::iterator it = t.begin();
589 for (dim_type k = 0; k < n; ++k)
590 for (dim_type j = 0; j < n; ++j)
592 *it = bgeot::to_scalar(hess_[i][j+k*n].eval(x.begin()));
615 bool complete=
false);
636 scalar_type alpha=0,
bool complete=
false);
656 const bgeot::pstored_point_tab pspt;
657 mutable std::vector<base_tensor> c;
658 mutable std::vector<base_tensor> pc;
659 mutable std::vector<base_tensor> hpc;
663 {
if (c.empty()) init_val();
return c[i]; }
666 {
if (pc.empty()) init_grad();
return pc[i]; }
669 {
if (hpc.empty()) init_hess();
return hpc[i]; }
670 inline pfem get_pfem()
const {
return pf; }
673 inline bgeot::pstored_point_tab get_ppoint_tab()
const
675 fem_precomp_(
const pfem,
const bgeot::pstored_point_tab);
676 ~fem_precomp_() { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this,
"Fem_precomp"); }
678 void init_val()
const;
679 void init_grad()
const;
680 void init_hess()
const;
702 dal::pstatic_stored_object dep);
717 std::set<pfem_precomp> precomps;
751 mutable base_matrix M_;
763 const base_matrix&
M()
const;
767 void base_value(base_tensor& t,
bool withM =
true)
const;
769 void pfp_base_value(base_tensor& t,
const pfem_precomp &pfp__);
775 void pfp_grad_base_value(base_tensor& t,
const pfem_precomp &pfp__);
784 bool is_convex_num_valid()
const;
785 void invalid_convex_num() { convex_num_ =
size_type(-1); }
793 pfem_precomp
pfp()
const {
return pfp_; }
794 void set_pfp(pfem_precomp newpfp);
795 void set_pf(
pfem newpf);
796 int xfem_side()
const {
return xfem_side_; }
797 void set_xfem_side(
int side) { xfem_side_ = side; }
798 void change(bgeot::pgeotrans_precomp pgp__,
800 const base_matrix& G__,
size_type convex_num__,
802 bgeot::geotrans_interpolation_context::change(pgp__,ii__,G__);
803 convex_num_ = convex_num__; face_num_ = face_num__; xfem_side_ = 0;
808 const base_matrix& G__,
size_type convex_num__,
810 bgeot::geotrans_interpolation_context::change
811 (pgt__, pfp__->get_ppoint_tab(), ii__, G__);
812 convex_num_ = convex_num__; face_num_ = face_num__; xfem_side_ = 0;
816 pfem pf__,
const base_node& xref__,
const base_matrix& G__,
818 bgeot::geotrans_interpolation_context::change(pgt__,xref__,G__);
819 pf_ = pf__; pfp_ = 0; convex_num_ = convex_num__; face_num_ = face_num__;
822 fem_interpolation_context()
823 :
bgeot::geotrans_interpolation_context(),
825 fem_interpolation_context(bgeot::pgeotrans_precomp pgp__,
827 const base_matrix& G__,
830 :
bgeot::geotrans_interpolation_context(pgp__,ii__,G__),
831 convex_num_(convex_num__), face_num_(face_num__), xfem_side_(0)
835 const base_matrix& G__,
838 :
bgeot::geotrans_interpolation_context(pgt__,pfp__->get_ppoint_tab(),
840 convex_num_(convex_num__), face_num_(face_num__), xfem_side_(0)
844 const base_node& xref__,
845 const base_matrix& G__,
848 :
bgeot::geotrans_interpolation_context(pgt__,xref__,G__),
849 pf_(pf__), pfp_(0), convex_num_(convex_num__), face_num_(face_num__),
856 template <
typename CVEC,
typename VVEC>
858 const CVEC& coeff, VVEC &val,
859 dim_type Qdim)
const {
862 GMM_ASSERT1(gmm::vect_size(val) == Qdim,
"dimensions mismatch");
863 GMM_ASSERT1(gmm::vect_size(coeff) == nbdof*Qmult,
864 "Wrong size for coeff vector");
871 typename gmm::linalg_traits<CVEC>::value_type co = coeff[j*Qmult+q];
873 val[r + q*
target_dim()] += co * Z[j + r*nbdof];
878 template <
typename MAT>
880 MAT &M, dim_type Qdim)
const {
883 GMM_ASSERT1(gmm::mat_nrows(M) == Qdim && gmm::mat_ncols(M) == nbdof*Qmult,
884 "dimensions mismatch");
891 M(r+q*
target_dim(), j*Qmult+q) = Z[j + r*nbdof];
900 template<
typename CVEC,
typename VMAT>
902 const CVEC& coeff, VMAT &val,
903 dim_type Qdim)
const {
906 size_type Qmult = gmm::vect_size(coeff) / nbdof;
907 GMM_ASSERT1(gmm::mat_ncols(val) == N &&
909 gmm::vect_size(coeff) == nbdof*Qmult,
910 "dimensions mismatch");
912 "dimensions mismatch");
918 base_tensor::const_iterator it = t.begin();
921 for (
size_type j = 0; j < nbdof; ++j, ++it)
922 val(r + q*
target_dim(), k) += coeff[j*Qmult+q] * (*it);
927 template<
typename CVEC,
typename VMAT>
929 const CVEC& coeff, VMAT &val,
930 dim_type Qdim)
const {
933 GMM_ASSERT1(gmm::mat_ncols(val) == N*N &&
934 gmm::mat_nrows(val) == Qdim,
"dimensions mismatch");
942 base_tensor::const_iterator it = t.begin();
945 for (
size_type j = 0; j < nbdof; ++j, ++it)
946 val(r + q*
target_dim(), k) += coeff[j*Qmult+q] * (*it);
954 template<
typename CVEC>
957 typename gmm::linalg_traits<CVEC>::value_type &val)
const {
960 size_type Qmult = gmm::vect_size(coeff) / nbdof;
961 GMM_ASSERT1(gmm::vect_size(coeff) == nbdof*Qmult ,
"dimensions mismatch");
964 "Dimensions mismatch. Divergence operator requires fem qdim equal to dim.");
970 val = scalar_type(0);
971 base_tensor::const_iterator it = t.begin();
974 if (k) it += (N*nbdof + 1);
977 val += coeff[j] * (*it);
985 val += coeff[j*N+k] * (*it);
1000 typedef dal::naming_system<virtual_fem>::param_list fem_param_list;
1005 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.