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"
69 void fem_global_function::update_from_context()
const {
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 std::map<size_type, std::vector<size_type>> box_to_convexes_map;
87 for (
size_type i=0; i < nb_total_dof; ++i) {
88 functions[i]->bounding_box(bmin, bmax);
89 box_to_convexes_map[boxtree.add_box(bmin, bmax, i)].push_back(i);
94 index_of_global_dof_.clear();
95 index_of_global_dof_.resize(m.nb_allocated_convex());
96 for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
97 GMM_ASSERT1(dim_ == m.structure_of_convex(cv)->dim(),
98 "Convexes of different dimension: to be done");
101 bounding_box(bmin, bmax, m.points_of_convex(cv), pgt);
103 bgeot::rtree::pbox_set boxlst;
104 boxtree.find_intersecting_boxes(bmin, bmax, boxlst);
105 index_of_global_dof_[cv].clear();
108 pintegration_method pim = mim.int_method_of_element(cv);
109 GMM_ASSERT1(pim->type() == IM_APPROX,
"You have to use approximated "
110 "integration in connection to a fem with global functions");
111 papprox_integration pai = pim->approx_method();
113 for (
const auto &box : boxlst) {
114 for (
auto candidate : box_to_convexes_map.at(box->id)) {
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[candidate]->is_in_support(gpt)) {
119 index_of_global_dof_[cv].push_back(candidate);
126 for (
const auto &box : boxlst) {
127 for (
auto candidate : box_to_convexes_map.at(box->id))
128 index_of_global_dof_[cv].push_back(candidate);
131 max_dof = std::max(max_dof, index_of_global_dof_[cv].size());
135 base_node P(dim()); gmm::fill(P,1./20);
136 std::vector<base_node> node_tab_(max_dof, P);
137 pspt_override = bgeot::store_point_tab(node_tab_);
139 dof_types_.resize(nb_total_dof);
140 std::fill(dof_types_.begin(), dof_types_.end(),
147 return (cv < index_of_global_dof_.size()) ? index_of_global_dof_[cv].size()
151 size_type fem_global_function::index_of_global_dof
155 return (cv < index_of_global_dof_.size() &&
156 i < index_of_global_dof_[cv].size()) ? index_of_global_dof_[cv][i]
160 bgeot::pconvex_ref fem_global_function::ref_convex(
size_type cv)
const {
162 return mim.int_method_of_element(cv)->approx_method()->ref_convex();
169 if (m.convex_index().is_in(cv))
171 (dim(), nb_dof(cv), m.structure_of_convex(cv)->nb_faces()));
172 else GMM_ASSERT1(
false,
"Wrong convex number: " << cv);
175 void fem_global_function::base_value(
const base_node &, base_tensor &)
const
176 { GMM_ASSERT1(
false,
"No base values, real only element."); }
177 void fem_global_function::grad_base_value(
const base_node &,
179 { GMM_ASSERT1(
false,
"No grad values, real only element."); }
180 void fem_global_function::hess_base_value(
const base_node &,
182 { GMM_ASSERT1(
false,
"No hess values, real only element."); }
185 base_tensor &t,
bool)
const {
186 assert(target_dim() == 1);
189 t.adjust_sizes(nbdof, target_dim());
191 GMM_ASSERT1(precomps,
"Internal error");
192 if (precomps->size() == 0)
193 precomps->resize(m.nb_allocated_convex());
194 GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(),
"Internal error");
195 const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
196 auto it = (*precomps)[cv].find(ptab);
197 if (it == (*precomps)[cv].end()) {
198 it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
205 if (it->second.val.size() == 0) {
206 it->second.val.resize(ptab->size());
208 bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
209 for (
size_type k = 0; k < ptab->size(); ++k) {
211 ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
212 real_base_value(ctx, it->second.val[k]);
215 gmm::copy(it->second.val[c.ii()].as_vector(), t.as_vector());
221 t[i] = functions[index_of_global_dof_[cv][i]]->val(c);
225 void fem_global_function::real_grad_base_value
227 assert(target_dim() == 1);
230 t.adjust_sizes(nbdof, target_dim(), dim());
232 GMM_ASSERT1(precomps,
"Internal error");
233 if (precomps->size() == 0)
234 precomps->resize(m.nb_allocated_convex());
235 GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(),
"Internal error");
236 const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
237 auto it = (*precomps)[cv].find(ptab);
238 if (it == (*precomps)[cv].end()) {
239 it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
242 if (it->second.grad.size() == 0) {
243 it->second.grad.resize(ptab->size());
245 bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
246 for (
size_type k = 0; k < ptab->size(); ++k) {
248 ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
249 real_grad_base_value(ctx, it->second.grad[k]);
252 gmm::copy(it->second.grad[c.ii()].as_vector(), t.as_vector());
254 base_small_vector G(dim());
256 functions[index_of_global_dof_[cv][i]]->grad(c,G);
258 t[j*nbdof + i] = G[j];
263 void fem_global_function::real_hess_base_value
265 assert(target_dim() == 1);
268 t.adjust_sizes(nbdof, target_dim(), gmm::sqr(dim()));
270 GMM_ASSERT1(precomps,
"Internal error");
271 if (precomps->size() == 0)
272 precomps->resize(m.nb_allocated_convex());
273 GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(),
"Internal error");
274 const bgeot::pstored_point_tab ptab = c.
pfp()->get_ppoint_tab();
275 auto it = (*precomps)[cv].find(ptab);
276 if (it == (*precomps)[cv].end()) {
277 it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
280 if (it->second.hess.size() == 0) {
281 it->second.hess.resize(ptab->size());
283 bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
284 for (
size_type k = 0; k < ptab->size(); ++k) {
286 ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
287 real_hess_base_value(ctx, it->second.hess[k]);
290 gmm::copy(it->second.hess[c.ii()].as_vector(), t.as_vector());
292 base_matrix H(dim(),dim());
294 functions[index_of_global_dof_[cv][i]]->hess(c,H);
296 t[jk*nbdof + i] = H[jk];
302 DAL_SIMPLE_KEY(special_fem_globf_key,
pfem);
306 pfem pf = std::make_shared<fem_global_function>(funcs, m);
307 dal::pstatic_stored_object_key
308 pk = std::make_shared<special_fem_globf_key>(pf);
315 pfem pf = std::make_shared<fem_global_function>(funcs, mim);
316 dal::pstatic_stored_object_key
317 pk = std::make_shared<special_fem_globf_key>(pf);