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" 58 fem_global_function::fem_global_function
59 (
const std::vector<pglobal_function> &funcs,
const mesh_im &mim_)
60 : functions(funcs), m(mim_.linked_mesh()), mim(mim_), has_mesh_im(true) {
62 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"Global function fem");
63 GMM_ASSERT1(&mim != &
dummy_mesh_im(),
"A non-empty mesh_im object" 72 for (
const auto &cv_precomps : *precomps)
73 for (
const auto &keyval : cv_precomps)
77 precomps = std::make_shared<precomp_pool>();
78 dal::pstatic_stored_object_key pkey
79 = std::make_shared<precomp_pool_key>(precomps);
84 base_node bmin(
dim()), bmax(
dim());
86 for (
size_type i=0; i < nb_total_dof; ++i) {
87 functions[i]->bounding_box(bmin, bmax);
88 boxtree.add_box(bmin, bmax, i);
91 scalar_type EPS=1E-13;
93 index_of_global_dof_.clear();
95 for (dal::bv_visitor cv(m.
convex_index()); !cv.finished(); ++cv) {
97 "Convexes of different dimension: to be done");
100 bounding_box(bmin, bmax, m.points_of_convex(cv), pgt);
101 for (
auto&& xx : bmin) xx -= EPS;
102 for (
auto&& xx : bmax) xx += EPS;
104 bgeot::rtree::pbox_set boxlst;
105 boxtree.find_intersecting_boxes(bmin, bmax, boxlst);
106 index_of_global_dof_[cv].clear();
110 GMM_ASSERT1(pim->type() == IM_APPROX,
"You have to use approximated " 111 "integration in connection to a fem with global functions");
112 papprox_integration pai = pim->approx_method();
114 for (
const auto &box : boxlst) {
115 for (
size_type k = 0; k < pai->nb_points(); ++k) {
116 base_node gpt = pgt->transform(pai->point(k),
117 m.points_of_convex(cv));
118 if (functions[box->id]->is_in_support(gpt)) {
119 index_of_global_dof_[cv].push_back(box->id);
125 for (
const auto &box : boxlst)
126 index_of_global_dof_[cv].push_back(box->id);
128 max_dof = std::max(max_dof, index_of_global_dof_[cv].size());
132 base_node P(
dim()); gmm::fill(P,1./20);
133 std::vector<base_node> node_tab_(max_dof, P);
134 pspt_override = bgeot::store_point_tab(node_tab_);
136 dof_types_.resize(nb_total_dof);
137 std::fill(dof_types_.begin(), dof_types_.end(),
144 return (cv < index_of_global_dof_.size()) ? index_of_global_dof_[cv].size()
148 size_type fem_global_function::index_of_global_dof
152 return (cv < index_of_global_dof_.size() &&
153 i < index_of_global_dof_[cv].size()) ? index_of_global_dof_[cv][i]
169 else GMM_ASSERT1(
false,
"Wrong convex number: " << cv);
173 { GMM_ASSERT1(
false,
"No base values, real only element."); }
176 { GMM_ASSERT1(
false,
"No grad values, real only element."); }
179 { GMM_ASSERT1(
false,
"No hess values, real only element."); }
182 base_tensor &t,
bool)
const {
188 GMM_ASSERT1(precomps,
"Internal error");
189 if (precomps->size() == 0)
192 const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
193 auto it = (*precomps)[cv].find(ptab);
194 if (it == (*precomps)[cv].end()) {
195 it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
202 if (it->second.val.size() == 0) {
203 it->second.val.resize(ptab->size());
205 bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
206 for (
size_type k = 0; k < ptab->size(); ++k) {
208 ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
212 gmm::copy(it->second.val[c.ii()].as_vector(), t.as_vector());
218 t[i] = functions[index_of_global_dof_[cv][i]]->val(c);
229 GMM_ASSERT1(precomps,
"Internal error");
230 if (precomps->size() == 0)
233 const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
234 auto it = (*precomps)[cv].find(ptab);
235 if (it == (*precomps)[cv].end()) {
236 it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
239 if (it->second.grad.size() == 0) {
240 it->second.grad.resize(ptab->size());
242 bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
243 for (
size_type k = 0; k < ptab->size(); ++k) {
245 ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
249 gmm::copy(it->second.grad[c.ii()].as_vector(), t.as_vector());
251 base_small_vector G(
dim());
253 functions[index_of_global_dof_[cv][i]]->grad(c,G);
255 t[j*nbdof + i] = G[j];
267 GMM_ASSERT1(precomps,
"Internal error");
268 if (precomps->size() == 0)
271 const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
272 auto it = (*precomps)[cv].find(ptab);
273 if (it == (*precomps)[cv].end()) {
274 it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
277 if (it->second.hess.size() == 0) {
278 it->second.hess.resize(ptab->size());
280 bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
281 for (
size_type k = 0; k < ptab->size(); ++k) {
283 ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
287 gmm::copy(it->second.hess[c.ii()].as_vector(), t.as_vector());
289 base_matrix H(
dim(),
dim());
291 functions[index_of_global_dof_[cv][i]]->hess(c,H);
293 t[jk*nbdof + i] = H[jk];
299 DAL_SIMPLE_KEY(special_fem_globf_key,
pfem);
303 pfem pf = std::make_shared<fem_global_function>(funcs, m);
304 dal::pstatic_stored_object_key
305 pk = std::make_shared<special_fem_globf_key>(pf);
312 pfem pf = std::make_shared<fem_global_function>(funcs, mim);
313 dal::pstatic_stored_object_key
314 pk = std::make_shared<special_fem_globf_key>(pf);
virtual pintegration_method int_method_of_element(size_type cv) const
return the integration method associated with an element (in no integration is associated, the function will crash! use the convex_index() of the mesh_im to check that a fem is associated to a given convex)
pconvex_ref basic_convex_ref(pconvex_ref cvr)
return the associated order 1 reference convex.
const mesh_im & dummy_mesh_im()
Dummy mesh_im for default parameter of functions.
void real_hess_base_value(const fem_interpolation_context &, base_tensor &, bool=true) const
Give the hessian of all components of the base functions at the current point of the fem_interpolatio...
size_type convex_num() const
get the current convex number
dim_type dim() const
dimension of the reference element.
bool have_pfp() const
true if a fem_precomp_ has been supplied.
Describe a mesh (collection of convexes (elements) and points).
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
Describe an integration method linked to a mesh.
void base_value(const base_node &, base_tensor &) const
Give the value of all components of the base functions at the point x of the reference element...
void hess_base_value(const base_node &, base_tensor &) const
Give the value of all hessians (on ref.
void real_base_value(const fem_interpolation_context &c, base_tensor &t, bool=true) const
Give the value of all components of the base functions at the current point of the fem_interpolation_...
size_t size_type
used as the common size type in the library
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
void real_grad_base_value(const fem_interpolation_context &c, base_tensor &t, bool=true) const
Give the gradient of all components of the base functions at the current point of the fem_interpolati...
structure passed as the argument of fem interpolation functions.
dim_type target_dim() const
dimension of the target space.
bool del_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
remove a dependency.
Define mesh_fem whose base functions are global function given by the user.
void add_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
Add a dependency, object o1 will depend on object o2.
GEneric Tool for Finite Element Methods.
pfem_precomp pfp() const
get the current fem_precomp_
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
size_type nb_allocated_convex() const
The number of convex indexes from 0 to the index of the last convex.
virtual const bgeot::convex< base_node > & node_convex(size_type cv) const
Gives the convex representing the nodes on the reference element.
virtual void update_from_context() const
this function has to be defined and should update the object when the context is modified.
virtual bgeot::pconvex_ref ref_convex(size_type cv) const
Return the convex 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
bool context_check() const
return true if update_from_context was called
virtual size_type nb_dof(size_type cv) const
Number of degrees of freedom.
pfem new_fem_global_function(const std::vector< pglobal_function > &funcs, const mesh &m)
create a new global function FEM.
pdof_description global_dof(dim_type d)
Description of a global dof, i.e.
Balanced tree of n-dimensional rectangles.
void grad_base_value(const base_node &, base_tensor &) const
Give the value of all gradients (on ref.
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation