131 #ifndef GETFEM_FEM_H__ 132 #define GETFEM_FEM_H__ 155 struct dof_description;
192 pdof_description bubble1_dof(dim_type ct);
200 pdof_description
product_dof(pdof_description pnd1, pdof_description pnd2);
202 pdof_description to_coord_dof(pdof_description p, dim_type ct);
211 dim_type coord_index_of_dof(pdof_description a);
213 int dof_weak_compatibility(pdof_description a, pdof_description b);
242 typedef std::shared_ptr<const getfem::virtual_fem>
pfem;
245 typedef std::shared_ptr<const getfem::fem_precomp_> pfem_precomp;
251 public std::enable_shared_from_this<const virtual_fem> {
253 enum vec_type { VECTORIAL_NOTRANSFORM_TYPE, VECTORIAL_PRIMAL_TYPE,
254 VECTORIAL_DUAL_TYPE };
258 mutable std::vector<pdof_description> dof_types_;
264 std::shared_ptr<bgeot::convex_structure> cvs_node;
265 std::vector<std::vector<short_type>> face_tab;
267 mutable bgeot::pstored_point_tab pspt;
268 mutable bool pspt_valid;
269 bgeot::pconvex_ref cvr;
270 dim_type ntarget_dim;
271 mutable dim_type dim_;
276 bool real_element_defined;
277 bool is_standard_fem;
282 std::string debug_name_;
292 {
return dof_types_.size(); }
298 {
return nb_base(cv) * ntarget_dim; }
300 {
return nb_dof(cv) * ntarget_dim; }
303 {
return dof_types_; }
304 short_type hierarchical_raff()
const {
return hier_raff; }
306 dim_type
dim()
const {
return dim_; }
307 dim_type &
dim() {
return dim_; }
315 bgeot::pconvex_ref &mref_convex() {
return cvr; }
325 const std::string &debug_name()
const {
return debug_name_; }
326 std::string &debug_name() {
return debug_name_; }
327 virtual bgeot::pstored_point_tab node_tab(
size_type)
const {
329 pspt = bgeot::store_point_tab(cv_node.points());
341 {
return (*(node_tab(cv)))[i];}
342 virtual const std::vector<short_type> &
344 bool is_on_real_element()
const {
return real_element_defined; }
345 bool is_equivalent()
const {
return is_equiv; }
347 {
return !(is_equivalent()) || real_element_defined; }
352 bool is_polynomialcomp()
const {
return is_polycomp; }
353 bool is_standard()
const {
return is_standard_fem; }
354 bool &is_polynomialcomp() {
return is_polycomp; }
355 bool &is_equivalent() {
return is_equiv; }
358 bool &is_standard() {
return is_standard_fem; }
359 short_type estimated_degree()
const {
return es_degree; }
360 short_type &estimated_degree() {
return es_degree; }
362 virtual void mat_trans(base_matrix &,
const base_matrix &,
364 { GMM_ASSERT1(
false,
"This function should not be called."); }
380 template<
typename CVEC,
typename VVEC>
382 const CVEC& coeff, VVEC &val, dim_type Qdim)
const;
390 template <
typename MAT>
392 MAT &M, dim_type Qdim)
const;
397 template<
typename CVEC,
typename VMAT>
399 const CVEC& coeff, VMAT &val,
400 dim_type Qdim=1)
const;
405 template<
typename CVEC,
typename VMAT>
407 const CVEC& coeff, VMAT &val,
408 dim_type Qdim)
const;
413 template<
typename CVEC>
416 typename gmm::linalg_traits<CVEC>::value_type &val)
const;
422 virtual void base_value(
const base_node &x, base_tensor &t)
const = 0;
428 virtual void grad_base_value(
const base_node &x, base_tensor &t)
const = 0;
434 virtual void hess_base_value(
const base_node &x, base_tensor &t)
const = 0;
442 base_tensor &t,
bool withM =
true)
const;
450 base_tensor &t,
bool withM =
true)
const;
458 base_tensor &t,
bool withM =
true)
const;
461 { GMM_ASSERT1(
false,
"internal error."); }
467 void add_node(
const pdof_description &d,
const base_node &pt,
468 const dal::bit_vector &faces);
469 void add_node(
const pdof_description &d,
const base_node &pt);
470 void init_cvs_node();
471 void unfreeze_cvs_node();
474 copy(f);
return *
this;
478 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"Fem");
479 ntarget_dim = 1; dim_ = 1;
480 is_equiv = is_pol = is_polycomp = is_lag = is_standard_fem =
false;
481 pspt_valid =
false; hier_raff = 0; real_element_defined =
false;
483 vtype = VECTORIAL_NOTRANSFORM_TYPE;
484 cvs_node = bgeot::new_convex_structure();
488 std::enable_shared_from_this<const virtual_fem>()
489 { copy(f); DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"Fem"); }
490 virtual ~
virtual_fem() { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this,
"Fem"); }
502 std::vector<FUNC> base_;
503 mutable std::vector<std::vector<FUNC>> grad_, hess_;
504 mutable bool grad_computed_;
505 mutable bool hess_computed_;
507 void compute_grad_()
const {
508 auto guard = getfem::omp_guard{};
509 if (grad_computed_)
return;
515 for (dim_type j = 0; j < n; ++j) {
516 grad_[i][j] = base_[i]; grad_[i][j].derivative(j);
519 grad_computed_ =
true;
522 void compute_hess_()
const {
523 auto guard = getfem::omp_guard{};
524 if (hess_computed_)
return;
529 hess_[i].resize(n*n);
530 for (dim_type j = 0; j < n; ++j) {
531 for (dim_type k = 0; k < n; ++k) {
532 hess_[i][j+k*n] = base_[i];
533 hess_[i][j+k*n].derivative(j); hess_[i][j+k*n].derivative(k);
537 hess_computed_ =
true;
543 const std::vector<FUNC> &
base()
const {
return base_; }
544 std::vector<FUNC> &base() {
return base_; }
548 bgeot::multi_index mi(2);
552 base_tensor::iterator it = t.begin();
554 *it = bgeot::to_scalar(base_[i].eval(x.begin()));
560 if (!grad_computed_) compute_grad_();
561 bgeot::multi_index mi(3);
566 base_tensor::iterator it = t.begin();
567 for (dim_type j = 0; j < n; ++j)
569 *it = bgeot::to_scalar(grad_[i][j].eval(x.begin()));
575 if (!hess_computed_) compute_hess_();
576 bgeot::multi_index mi(4);
582 base_tensor::iterator it = t.begin();
583 for (dim_type k = 0; k < n; ++k)
584 for (dim_type j = 0; j < n; ++j)
586 *it = bgeot::to_scalar(hess_[i][j+k*n].eval(x.begin()));
589 fem() : grad_computed_(
false), hess_computed_(
false){}
611 bool complete=
false);
631 scalar_type alpha=0,
bool complete=
false);
651 const bgeot::pstored_point_tab pspt;
652 mutable std::vector<base_tensor> c;
653 mutable std::vector<base_tensor> pc;
654 mutable std::vector<base_tensor> hpc;
658 {
if (c.empty()) init_val();
return c[i]; }
661 {
if (pc.empty()) init_grad();
return pc[i]; }
664 {
if (hpc.empty()) init_hess();
return hpc[i]; }
665 inline pfem get_pfem()
const {
return pf; }
668 inline bgeot::pstored_point_tab get_ppoint_tab()
const 670 fem_precomp_(
const pfem,
const bgeot::pstored_point_tab);
671 ~
fem_precomp_() { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this,
"Fem_precomp"); }
673 void init_val()
const;
674 void init_grad()
const;
675 void init_hess()
const;
696 pfem_precomp
fem_precomp(pfem pf, bgeot::pstored_point_tab pspt,
697 dal::pstatic_stored_object dep);
712 std::set<pfem_precomp> precomps;
727 pfem_precomp
operator()(pfem pf, bgeot::pstored_point_tab pspt) {
744 mutable base_matrix M_;
756 const base_matrix& M()
const;
760 void base_value(base_tensor& t,
bool withM =
true)
const;
762 void pfp_base_value(base_tensor& t,
const pfem_precomp &pfp__);
768 void pfp_grad_base_value(base_tensor& t,
const pfem_precomp &pfp__);
774 const pfem
pf()
const {
return pf_; }
777 bool is_convex_num_valid()
const;
778 void invalid_convex_num() { convex_num_ =
size_type(-1); }
784 bool is_on_face()
const;
786 pfem_precomp
pfp()
const {
return pfp_; }
787 void set_pfp(pfem_precomp newpfp);
788 void set_pf(pfem newpf);
789 int xfem_side()
const {
return xfem_side_; }
790 void set_xfem_side(
int side) { xfem_side_ = side; }
791 void change(bgeot::pgeotrans_precomp pgp__,
793 const base_matrix& G__,
size_type convex_num__,
795 bgeot::geotrans_interpolation_context::change(pgp__,ii__,G__);
796 convex_num_ = convex_num__; face_num_ = face_num__; xfem_side_ = 0;
801 const base_matrix& G__,
size_type convex_num__,
803 bgeot::geotrans_interpolation_context::change
804 (pgt__, pfp__->get_ppoint_tab(), ii__, G__);
805 convex_num_ = convex_num__; face_num_ = face_num__; xfem_side_ = 0;
809 pfem pf__,
const base_node& xref__,
const base_matrix& G__,
811 bgeot::geotrans_interpolation_context::change(pgt__,xref__,G__);
812 pf_ = pf__; pfp_ = 0; convex_num_ = convex_num__; face_num_ = face_num__;
820 const base_matrix& G__,
824 convex_num_(convex_num__), face_num_(face_num__), xfem_side_(0)
828 const base_matrix& G__,
833 convex_num_(convex_num__), face_num_(face_num__), xfem_side_(0)
837 const base_node& xref__,
838 const base_matrix& G__,
842 pf_(pf__), pfp_(0), convex_num_(convex_num__), face_num_(face_num__),
849 template <
typename CVEC,
typename VVEC>
851 const CVEC& coeff, VVEC &val,
852 dim_type Qdim)
const {
855 GMM_ASSERT1(gmm::vect_size(val) == Qdim,
"dimensions mismatch");
856 GMM_ASSERT1(gmm::vect_size(coeff) == nbdof*Qmult,
857 "Wrong size for coeff vector");
864 typename gmm::linalg_traits<CVEC>::value_type co = coeff[j*Qmult+q];
866 val[r + q*
target_dim()] += co * Z[j + r*nbdof];
871 template <
typename MAT>
873 MAT &M, dim_type Qdim)
const {
876 GMM_ASSERT1(gmm::mat_nrows(M) == Qdim && gmm::mat_ncols(M) == nbdof*Qmult,
877 "dimensions mismatch");
884 M(r+q*
target_dim(), j*Qmult+q) = Z[j + r*nbdof];
893 template<
typename CVEC,
typename VMAT>
895 const CVEC& coeff, VMAT &val,
896 dim_type Qdim)
const {
899 size_type Qmult = gmm::vect_size(coeff) / nbdof;
900 GMM_ASSERT1(gmm::mat_ncols(val) == N &&
902 gmm::vect_size(coeff) == nbdof*Qmult,
903 "dimensions mismatch");
905 "dimensions mismatch");
911 base_tensor::const_iterator it = t.begin();
914 for (
size_type j = 0; j < nbdof; ++j, ++it)
915 val(r + q*
target_dim(), k) += coeff[j*Qmult+q] * (*it);
920 template<
typename CVEC,
typename VMAT>
922 const CVEC& coeff, VMAT &val,
923 dim_type Qdim)
const {
926 GMM_ASSERT1(gmm::mat_ncols(val) == N*N &&
927 gmm::mat_nrows(val) == Qdim,
"dimensions mismatch");
935 base_tensor::const_iterator it = t.begin();
938 for (
size_type j = 0; j < nbdof; ++j, ++it)
939 val(r + q*
target_dim(), k) += coeff[j*Qmult+q] * (*it);
947 template<
typename CVEC>
950 typename gmm::linalg_traits<CVEC>::value_type &val)
const {
953 size_type Qmult = gmm::vect_size(coeff) / nbdof;
954 GMM_ASSERT1(gmm::vect_size(coeff) == nbdof*Qmult ,
"dimensions mismatch");
957 "Dimensions mismatch. Divergence operator requires fem qdim equal to dim.");
963 val = scalar_type(0);
964 base_tensor::const_iterator it = t.begin();
967 if (k) it += (N*nbdof + 1);
970 val += coeff[j] * (*it);
978 val += coeff[j*N+k] * (*it);
988 typedef dal::naming_system<virtual_fem>::param_list fem_param_list;
993 void add_fem_name(std::string name,
virtual size_type nb_base(size_type cv) const
Number of basis functions.
Geometric transformations on convexes.
dof_description * pdof_description
Type representing a pointer on a dof_description.
base_poly read_base_poly(short_type n, std::istream &f)
read a base_poly on the stream ist.
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.
base class for static stored objects
Handle composite polynomials.
Stores interdependent getfem objects.
virtual size_type nb_dof(size_type) const
Number of degrees of freedom.
vec_type vectorial_type() const
Type of vectorial element.
virtual void hess_base_value(const base_node &x, base_tensor &t) const =0
Give the value of all hessians (on ref.
size_type convex_num() const
get the current convex number
Pre-computations on a fem (given a fixed set of points on the reference convex, this object computes ...
Base class for finite element description.
dim_type dim() const
dimension of the reference element.
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
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.
const std::vector< FUNC > & base() const
Gives the array of basic functions (components).
bool have_pfp() const
true if a fem_precomp_ has been supplied.
const base_tensor & val(size_type i) const
returns values of the base functions
virtual bgeot::pconvex_ref ref_convex(size_type) const
Return the convex of the reference element.
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...
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...
bgeot::pconvex_structure basic_structure(size_type cv) const
Gives the convex of the reference element.
the geotrans_interpolation_context structure is passed as the argument of geometric transformation in...
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.
void del_stored_object(const pstatic_stored_object &o, bool ignore_unstored)
Delete an object and the object which depend on it.
Integration methods (exact and approximated) on convexes.
virtual_fem implementation as a vector of generic functions.
pfem_precomp operator()(pfem pf, bgeot::pstored_point_tab pspt)
Request a pfem_precomp.
virtual const bgeot::convex< base_node > & node_convex(size_type) const
Gives the convex representing the nodes on the reference element.
void interpolation_diverg(const fem_interpolation_context &c, const CVEC &coeff, typename gmm::linalg_traits< CVEC >::value_type &val) const
Interpolation of the divergence.
pdof_description product_dof(pdof_description pnd1, pdof_description pnd2)
Product description of the descriptions *pnd1 and *pnd2.
size_type nb_base_components(size_type cv) const
Number of components (nb_dof() * dimension of the target space).
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.
Associate a name to a method descriptor and store method descriptors.
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
bool dof_compatibility(pdof_description, pdof_description)
Says if the two dofs can be identified.
bgeot::pconvex_structure structure(size_type cv) const
Gives the convex structure of the reference element nodes.
pdof_description derivative_dof(dim_type d, dim_type r)
Description of a unique dof of derivative type.
std::string name_of_fem(pfem p)
get the string name of a fem descriptor.
structure passed as the argument of fem interpolation functions.
void interpolation_hess(const fem_interpolation_context &c, const CVEC &coeff, VMAT &val, dim_type Qdim) const
Interpolation of the hessian.
dim_type target_dim() const
dimension of the target space.
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...
const fem< bgeot::base_poly > * ppolyfem
Classical polynomial FEM.
GEneric Tool for Finite Element Methods.
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_...
pdof_description lagrange_dof(dim_type d)
Description of a unique dof of lagrange type (value at the node).
pfem_precomp pfp() const
get the current fem_precomp_
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
bool dof_linkable(pdof_description)
Says if the dof is linkable.
bool is_lagrange() const
true if the base functions are such that
const fem< bgeot::polynomial_composite > * ppolycompfem
Polynomial composite FEM.
gmm::uint16_type short_type
used as the common short type integer in the library
pdof_description mean_value_dof(dim_type d)
Description of a unique dof of mean value type.
pdof_description normal_derivative_dof(dim_type d)
Description of a unique dof of normal derivative type (normal derivative at the node, regarding a face).
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.
void delete_fem_precomp(pfem_precomp pfp)
Request for the removal of a pfem_precomp.
void set_face_num(short_type f)
set the current face number
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...
const pfem pf() const
get the current FEM descriptor
size_type dof_xfem_index(pdof_description)
Returns the xfem_index of dof (0 for normal dof)
virtual void grad_base_value(const base_node &x, base_tensor &t) const =0
Give the value of all gradients (on ref.
const fem< bgeot::base_rational_fraction > * prationalfracfem
Rational fration FEM.
bool have_pf() const
true if the pfem is available.
const base_node & node_of_dof(size_type cv, size_type i) const
Gives the node corresponding to the dof i.
pdof_description xfem_dof(pdof_description p, size_type ind)
Description of a special dof for Xfem.
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) ...
pdof_description global_dof(dim_type d)
Description of a global dof, i.e.
const std::vector< pdof_description > & dof_types() const
Get the array of pointer on dof description.
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...
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
bool is_polynomial() const
true if the base functions are polynomials
const base_tensor & grad(size_type i) const
returns gradients of the base functions
const base_tensor & hess(size_type i) const
returns hessians of the base functions
void interpolation_grad(const fem_interpolation_context &c, const CVEC &coeff, VMAT &val, dim_type Qdim=1) const
Interpolation of the gradient.
int dof_description_compare(pdof_description a, pdof_description b)
Gives a total order on the dof description compatible with the identification.