28   void fem_global_function::init() {
 
   29     is_pol = is_lag = is_standard_fem = 
false; es_degree = 5;
 
   30     is_equiv = real_element_defined = 
true;
 
   34     nm << 
"GLOBAL_FEM(" << (
void*)
this << 
")";
 
   35     debug_name_ = nm.str();
 
   37     GMM_ASSERT1(functions.size() > 0, 
"Empty list of base functions.");
 
   38     dim_ = functions[0]->dim();
 
   39     for (
size_type i=1; i < functions.size(); ++i)
 
   40       GMM_ASSERT1(dim_ == functions[i]->
dim(),
 
   41                   "Incompatible function space dimensions.");
 
   47   fem_global_function::fem_global_function
 
   48   (
const std::vector<pglobal_function> &funcs, 
const mesh &m_)
 
   49     : functions(funcs), m(m_), mim(
dummy_mesh_im()), has_mesh_im(false) {
 
   51     DAL_STORED_OBJECT_DEBUG_CREATED(
this, 
"Global function fem");
 
   52     GMM_ASSERT1(&m != &dummy_mesh(), 
"A non-empty mesh object" 
   55     for (
const pglobal_function &glob_func : funcs) {
 
   56       std::shared_ptr<const context_dependencies>
 
   57         dep = std::dynamic_pointer_cast<const context_dependencies>(glob_func);
 
   64   fem_global_function::fem_global_function
 
   65   (
const std::vector<pglobal_function> &funcs, 
const mesh_im &mim_)
 
   66     : functions(funcs), m(mim_.linked_mesh()), mim(mim_), has_mesh_im(true) {
 
   68     DAL_STORED_OBJECT_DEBUG_CREATED(
this, 
"Global function fem");
 
   69     GMM_ASSERT1(&mim != &
dummy_mesh_im(), 
"A non-empty mesh_im object" 
   75   void fem_global_function::update_from_context()
 const {
 
   78       for (
const auto &cv_precomps : *precomps)
 
   79         for (
const auto &keyval : cv_precomps)
 
   83       precomps = std::make_shared<precomp_pool>();
 
   84       dal::pstatic_stored_object_key pkey
 
   85         = std::make_shared<precomp_pool_key>(precomps);
 
   90     base_node bmin(dim()), bmax(dim());
 
   92     std::map<size_type, std::vector<size_type>> box_to_convexes_map;
 
   93     for (
size_type i=0; i < nb_total_dof; ++i) {
 
   94       functions[i]->bounding_box(bmin, bmax);
 
   95       box_to_convexes_map[boxtree.add_box(bmin, bmax, i)].push_back(i);
 
  100     index_of_global_dof_.clear();
 
  101     index_of_global_dof_.resize(m.nb_allocated_convex());
 
  102     for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
 
  103       GMM_ASSERT1(dim_ == m.structure_of_convex(cv)->dim(),
 
  104                   "Convexes of different dimension: to be done");
 
  107       bounding_box(bmin, bmax, m.points_of_convex(cv), pgt);
 
  109       bgeot::rtree::pbox_set boxlst;
 
  110       boxtree.find_intersecting_boxes(bmin, bmax, boxlst);
 
  111       index_of_global_dof_[cv].clear();
 
  114         pintegration_method pim = mim.int_method_of_element(cv);
 
  115         GMM_ASSERT1(pim->type() == IM_APPROX, 
"You have to use approximated " 
  116                     "integration in connection to a fem with global functions");
 
  117         papprox_integration pai = pim->approx_method();
 
  119         for (
const auto &box : boxlst) {
 
  120           for (
auto candidate : box_to_convexes_map.at(box->id)) {
 
  121             for (
size_type k = 0; k < pai->nb_points(); ++k) {
 
  122               base_node gpt = pgt->transform(pai->point(k),
 
  123                                              m.points_of_convex(cv));
 
  124               if (functions[candidate]->is_in_support(gpt)) {
 
  125                 index_of_global_dof_[cv].push_back(candidate);
 
  132         for (
const auto &box : boxlst) {
 
  133           for (
auto candidate : box_to_convexes_map.at(box->id))
 
  134             index_of_global_dof_[cv].push_back(candidate);
 
  137       max_dof = std::max(max_dof, index_of_global_dof_[cv].size());
 
  141     base_node P(dim()); gmm::fill(P,1./20);
 
  142     std::vector<base_node> node_tab_(max_dof, P);
 
  143     pspt_override = bgeot::store_point_tab(node_tab_);
 
  145     dof_types_.resize(nb_total_dof);
 
  146     std::fill(dof_types_.begin(), dof_types_.end(),
 
  153     return (cv < index_of_global_dof_.size()) ? index_of_global_dof_[cv].size()
 
  157   size_type fem_global_function::index_of_global_dof
 
  161     return (cv < index_of_global_dof_.size() &&
 
  162             i < index_of_global_dof_[cv].size()) ? index_of_global_dof_[cv][i]
 
  166   bgeot::pconvex_ref fem_global_function::ref_convex(
size_type cv)
 const {
 
  168       return mim.int_method_of_element(cv)->approx_method()->ref_convex();
 
  175     if (m.convex_index().is_in(cv))
 
  177                (dim(), nb_dof(cv), m.structure_of_convex(cv)->nb_faces()));
 
  178     else GMM_ASSERT1(
false, 
"Wrong convex number: " << cv);
 
  181   void fem_global_function::base_value(
const base_node &, base_tensor &)
 const 
  182   { GMM_ASSERT1(
false, 
"No base values, real only element."); }
 
  183   void fem_global_function::grad_base_value(
const base_node &,
 
  185   { GMM_ASSERT1(
false, 
"No grad values, real only element."); }
 
  186   void fem_global_function::hess_base_value(
const base_node &,
 
  188   { GMM_ASSERT1(
false, 
"No hess values, real only element."); }
 
  191                                             base_tensor &t, 
bool)
 const {
 
  192     assert(target_dim() == 1);
 
  195     t.adjust_sizes(nbdof, target_dim());
 
  197       GMM_ASSERT1(precomps, 
"Internal error");
 
  198       if (precomps->size() == 0)
 
  199         precomps->resize(m.nb_allocated_convex());
 
  200       GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(), 
"Internal error");
 
  201       const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
 
  202       auto it = (*precomps)[cv].find(ptab);
 
  203       if (it == (*precomps)[cv].end()) {
 
  204         it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
 
  211       if (it->second.val.size() == 0) {
 
  212         it->second.val.resize(ptab->size());
 
  214         bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
 
  215         for (
size_type k = 0; k < ptab->size(); ++k) {
 
  217             ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
 
  218           real_base_value(ctx, it->second.val[k]);
 
  221       gmm::copy(it->second.val[c.ii()].as_vector(), t.as_vector());
 
  227         t[i] = functions[index_of_global_dof_[cv][i]]->val(c);
 
  231   void fem_global_function::real_grad_base_value
 
  233     assert(target_dim() == 1);
 
  236     t.adjust_sizes(nbdof, target_dim(), dim());
 
  238       GMM_ASSERT1(precomps, 
"Internal error");
 
  239       if (precomps->size() == 0)
 
  240         precomps->resize(m.nb_allocated_convex());
 
  241       GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(), 
"Internal error");
 
  242       const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
 
  243       auto it = (*precomps)[cv].find(ptab);
 
  244       if (it == (*precomps)[cv].end()) {
 
  245         it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
 
  248       if (it->second.grad.size() == 0) {
 
  249         it->second.grad.resize(ptab->size());
 
  251         bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
 
  252         for (
size_type k = 0; k < ptab->size(); ++k) {
 
  254             ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
 
  255           real_grad_base_value(ctx, it->second.grad[k]);
 
  258       gmm::copy(it->second.grad[c.ii()].as_vector(), t.as_vector());
 
  260       base_small_vector G(dim());
 
  262         functions[index_of_global_dof_[cv][i]]->grad(c,G);
 
  264           t[j*nbdof + i] = G[j];
 
  269   void fem_global_function::real_hess_base_value
 
  271     assert(target_dim() == 1);
 
  274     t.adjust_sizes(nbdof, target_dim(), gmm::sqr(dim()));
 
  276       GMM_ASSERT1(precomps, 
"Internal error");
 
  277       if (precomps->size() == 0)
 
  278         precomps->resize(m.nb_allocated_convex());
 
  279       GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(), 
"Internal error");
 
  280       const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
 
  281       auto it = (*precomps)[cv].find(ptab);
 
  282       if (it == (*precomps)[cv].end()) {
 
  283         it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
 
  286       if (it->second.hess.size() == 0) {
 
  287         it->second.hess.resize(ptab->size());
 
  289         bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
 
  290         for (
size_type k = 0; k < ptab->size(); ++k) {
 
  292             ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
 
  293           real_hess_base_value(ctx, it->second.hess[k]);
 
  296       gmm::copy(it->second.hess[c.ii()].as_vector(), t.as_vector());
 
  298       base_matrix H(dim(),dim());
 
  300         functions[index_of_global_dof_[cv][i]]->hess(c,H);
 
  302           t[jk*nbdof + i] = H[jk];
 
  308   DAL_SIMPLE_KEY(special_fem_globf_key, 
pfem);
 
  312     pfem pf = std::make_shared<fem_global_function>(funcs, m);
 
  313     dal::pstatic_stored_object_key
 
  314       pk = std::make_shared<special_fem_globf_key>(pf);
 
  321     pfem pf = std::make_shared<fem_global_function>(funcs, mim);
 
  322     dal::pstatic_stored_object_key
 
  323       pk = std::make_shared<special_fem_globf_key>(pf);
 
Balanced tree of n-dimensional rectangles.
 
virtual void update_from_context() const
this function has to be defined and should update the object when the context is modified.
 
structure passed as the argument of fem interpolation functions.
 
Describe an integration method linked to a mesh.
 
Describe a mesh (collection of convexes (elements) and points).
 
Define mesh_fem whose base functions are global function given by the user.
 
pdof_description global_dof(dim_type d)
Description of a global dof, i.e.
 
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
 
bool have_pfp() const
true if a fem_precomp_ has been supplied.
 
pfem_precomp pfp() const
get the current fem_precomp_
 
dim_type dim() const
dimension of the reference element.
 
pconvex_ref generic_dummy_convex_ref(dim_type nc, size_type n, short_type nf)
generic convex with n global nodes
 
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
 
pconvex_ref basic_convex_ref(pconvex_ref cvr)
return the associated order 1 reference convex.
 
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
 
void add_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
Add a dependency, object o1 will depend on object o2.
 
bool del_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
remove a dependency.
 
GEneric Tool for Finite Element Methods.
 
const mesh_im & dummy_mesh_im()
Dummy mesh_im for default parameter of functions.
 
pfem new_fem_global_function(const std::vector< pglobal_function > &funcs, const mesh &m)
create a new global function FEM.