27 void fem_global_function::init() {
28 is_pol = is_lag = is_standard_fem =
false; es_degree = 5;
29 is_equiv = real_element_defined =
true;
33 nm <<
"GLOBAL_FEM(" << (
void*)
this <<
")";
34 debug_name_ = nm.str();
36 GMM_ASSERT1(functions.size() > 0,
"Empty list of base functions.");
37 dim_ = functions[0]->dim();
38 for (
size_type i=1; i < functions.size(); ++i)
39 GMM_ASSERT1(dim_ == functions[i]->
dim(),
40 "Incompatible function space dimensions.");
46 fem_global_function::fem_global_function
47 (
const std::vector<pglobal_function> &funcs,
const mesh &m_)
48 : functions(funcs), m(m_), mim(
dummy_mesh_im()), has_mesh_im(false) {
50 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"Global function fem");
51 GMM_ASSERT1(&m != &dummy_mesh(),
"A non-empty mesh object"
54 for (
const pglobal_function &glob_func : funcs) {
55 std::shared_ptr<const context_dependencies>
56 dep = std::dynamic_pointer_cast<const context_dependencies>(glob_func);
63 fem_global_function::fem_global_function
64 (
const std::vector<pglobal_function> &funcs,
const mesh_im &mim_)
65 : functions(funcs), m(mim_.linked_mesh()), mim(mim_), has_mesh_im(true) {
67 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"Global function fem");
68 GMM_ASSERT1(&mim != &
dummy_mesh_im(),
"A non-empty mesh_im object"
74 void fem_global_function::update_from_context()
const {
77 for (
const auto &cv_precomps : *precomps)
78 for (
const auto &keyval : cv_precomps)
82 precomps = std::make_shared<precomp_pool>();
83 dal::pstatic_stored_object_key pkey
84 = std::make_shared<precomp_pool_key>(precomps);
89 base_node bmin(dim()), bmax(dim());
91 std::map<size_type, std::vector<size_type>> box_to_convexes_map;
92 for (
size_type i=0; i < nb_total_dof; ++i) {
93 functions[i]->bounding_box(bmin, bmax);
94 box_to_convexes_map[boxtree.add_box(bmin, bmax, i)].push_back(i);
99 index_of_global_dof_.clear();
100 index_of_global_dof_.resize(m.nb_allocated_convex());
101 for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
102 GMM_ASSERT1(dim_ == m.structure_of_convex(cv)->dim(),
103 "Convexes of different dimension: to be done");
106 bounding_box(bmin, bmax, m.points_of_convex(cv), pgt);
108 bgeot::rtree::pbox_set boxlst;
109 boxtree.find_intersecting_boxes(bmin, bmax, boxlst);
110 index_of_global_dof_[cv].clear();
113 pintegration_method pim = mim.int_method_of_element(cv);
114 GMM_ASSERT1(pim->type() == IM_APPROX,
"You have to use approximated "
115 "integration in connection to a fem with global functions");
116 papprox_integration pai = pim->approx_method();
118 for (
const auto &box : boxlst) {
119 for (
auto candidate : box_to_convexes_map.at(box->id)) {
120 for (
size_type k = 0; k < pai->nb_points(); ++k) {
121 base_node gpt = pgt->transform(pai->point(k),
122 m.points_of_convex(cv));
123 if (functions[candidate]->is_in_support(gpt)) {
124 index_of_global_dof_[cv].push_back(candidate);
131 for (
const auto &box : boxlst) {
132 for (
auto candidate : box_to_convexes_map.at(box->id))
133 index_of_global_dof_[cv].push_back(candidate);
136 max_dof = std::max(max_dof, index_of_global_dof_[cv].size());
140 base_node P(dim()); gmm::fill(P,1./20);
141 std::vector<base_node> node_tab_(max_dof, P);
142 pspt_override = bgeot::store_point_tab(node_tab_);
144 dof_types_.resize(nb_total_dof);
145 std::fill(dof_types_.begin(), dof_types_.end(),
152 return (cv < index_of_global_dof_.size()) ? index_of_global_dof_[cv].size()
156 size_type fem_global_function::index_of_global_dof
160 return (cv < index_of_global_dof_.size() &&
161 i < index_of_global_dof_[cv].size()) ? index_of_global_dof_[cv][i]
165 bgeot::pconvex_ref fem_global_function::ref_convex(
size_type cv)
const {
167 return mim.int_method_of_element(cv)->approx_method()->ref_convex();
174 if (m.convex_index().is_in(cv))
176 (dim(), nb_dof(cv), m.structure_of_convex(cv)->nb_faces()));
177 else GMM_ASSERT1(
false,
"Wrong convex number: " << cv);
180 void fem_global_function::base_value(
const base_node &, base_tensor &)
const
181 { GMM_ASSERT1(
false,
"No base values, real only element."); }
182 void fem_global_function::grad_base_value(
const base_node &,
184 { GMM_ASSERT1(
false,
"No grad values, real only element."); }
185 void fem_global_function::hess_base_value(
const base_node &,
187 { GMM_ASSERT1(
false,
"No hess values, real only element."); }
190 base_tensor &t,
bool)
const {
191 assert(target_dim() == 1);
194 t.adjust_sizes(nbdof, target_dim());
196 GMM_ASSERT1(precomps,
"Internal error");
197 if (precomps->size() == 0)
198 precomps->resize(m.nb_allocated_convex());
199 GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(),
"Internal error");
200 const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
201 auto it = (*precomps)[cv].find(ptab);
202 if (it == (*precomps)[cv].end()) {
203 it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
210 if (it->second.val.size() == 0) {
211 it->second.val.resize(ptab->size());
213 bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
214 for (
size_type k = 0; k < ptab->size(); ++k) {
216 ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
217 real_base_value(ctx, it->second.val[k]);
220 gmm::copy(it->second.val[c.ii()].as_vector(), t.as_vector());
226 t[i] = functions[index_of_global_dof_[cv][i]]->val(c);
230 void fem_global_function::real_grad_base_value
232 assert(target_dim() == 1);
235 t.adjust_sizes(nbdof, target_dim(), dim());
237 GMM_ASSERT1(precomps,
"Internal error");
238 if (precomps->size() == 0)
239 precomps->resize(m.nb_allocated_convex());
240 GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(),
"Internal error");
241 const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
242 auto it = (*precomps)[cv].find(ptab);
243 if (it == (*precomps)[cv].end()) {
244 it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
247 if (it->second.grad.size() == 0) {
248 it->second.grad.resize(ptab->size());
250 bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
251 for (
size_type k = 0; k < ptab->size(); ++k) {
253 ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
254 real_grad_base_value(ctx, it->second.grad[k]);
257 gmm::copy(it->second.grad[c.ii()].as_vector(), t.as_vector());
259 base_small_vector G(dim());
261 functions[index_of_global_dof_[cv][i]]->grad(c,G);
263 t[j*nbdof + i] = G[j];
268 void fem_global_function::real_hess_base_value
270 assert(target_dim() == 1);
273 t.adjust_sizes(nbdof, target_dim(), gmm::sqr(dim()));
275 GMM_ASSERT1(precomps,
"Internal error");
276 if (precomps->size() == 0)
277 precomps->resize(m.nb_allocated_convex());
278 GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(),
"Internal error");
279 const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
280 auto it = (*precomps)[cv].find(ptab);
281 if (it == (*precomps)[cv].end()) {
282 it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
285 if (it->second.hess.size() == 0) {
286 it->second.hess.resize(ptab->size());
288 bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
289 for (
size_type k = 0; k < ptab->size(); ++k) {
291 ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
292 real_hess_base_value(ctx, it->second.hess[k]);
295 gmm::copy(it->second.hess[c.ii()].as_vector(), t.as_vector());
297 base_matrix H(dim(),dim());
299 functions[index_of_global_dof_[cv][i]]->hess(c,H);
301 t[jk*nbdof + i] = H[jk];
307 DAL_SIMPLE_KEY(special_fem_globf_key,
pfem);
311 pfem pf = std::make_shared<fem_global_function>(funcs, m);
312 dal::pstatic_stored_object_key
313 pk = std::make_shared<special_fem_globf_key>(pf);
320 pfem pf = std::make_shared<fem_global_function>(funcs, mim);
321 dal::pstatic_stored_object_key
322 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.