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.