26 void interpolated_fem::build_rtree(
void)
const {
29 box_to_convexes_map.clear();
30 for (dal::bv_visitor cv(mf.
convex_index()); !cv.finished(); ++cv) {
31 bounding_box(min, max, mf.
linked_mesh().points_of_convex(cv),
33 box_to_convexes_map[boxtree.add_box(min, max, cv)].push_back(cv);
38 bool interpolated_fem::find_a_point(base_node pt, base_node &ptr,
41 if (pif) { base_node ptreal = pt; pif->val(ptreal, pt); }
43 { cv = cv_stored;
if (gt_invertible)
return true; }
44 boxtree.find_boxes_at_point(pt, boxlst);
45 bgeot::rtree::pbox_set::const_iterator it = boxlst.begin(),
47 for (; it != ite; ++it) {
48 for (
auto candidate : box_to_convexes_map.at((*it)->id)) {
52 cv_stored = candidate;
53 if (gic.
invert(pt, ptr, gt_invertible)) {
54 cv = candidate;
return true;
67 "Interpolated fem works only on non reduced mesh_fems");
69 std::vector<elt_interpolation_data> vv(mim.
convex_index().last_true() + 1);
73 dal::bit_vector alldofs;
76 for (dal::bv_visitor cv(mim.
convex_index()); !cv.finished(); ++cv) {
77 if (dim_ == dim_type(-1))
81 "Convexes of different dimension: to be done");
83 GMM_ASSERT1(pim->type() == IM_APPROX,
"You have to use approximated "
84 "integration to interpolate a fem");
85 papprox_integration pai = pim->approx_method();
87 elements[cv].gausspt.resize(pai->nb_points());
90 for (
size_type k = 0; k < pai->nb_points(); ++k) {
91 gausspt_interpolation_data &gpid = elements[cv].gausspt[k];
93 gpt = pgt->transform(pai->point(k),
95 gpid.iflags = find_a_point(gpt, gpid.ptref, gpid.elt) ? 1 : 0;
96 if (gpid.iflags && last_cv != gpid.elt) {
100 if (!(blocked_dof[idof])) dofs.add(idof);
105 elements[cv].nb_dof = dofs.card();
106 elements[cv].pim = pim;
107 max_dof = std::max(max_dof, dofs.card());
108 elements[cv].inddof.resize(dofs.card());
110 for (dal::bv_visitor idof(dofs); !idof.finished(); ++idof)
111 { elements[cv].inddof[cnt] = idof; ind_dof[idof] = cnt++; }
112 for (
size_type k = 0; k < pai->nb_points(); ++k) {
113 gausspt_interpolation_data &gpid = elements[cv].gausspt[k];
116 gpid.local_dof.resize(nbd);
119 gpid.local_dof[i] = dofs.is_in(ndof) ? ind_dof[ndof]
127 base_node P(
dim()); gmm::fill(P,1./20);
128 std::vector<base_node> node_tab_(max_dof, P);
129 pspt_override = bgeot::store_point_tab(node_tab_);
131 dof_types_.resize(max_dof);
132 std::fill(dof_types_.begin(), dof_types_.end(),
138 std::fill(ind_dof.begin(), ind_dof.end(),
size_type(-1));
144 return elements[cv].nb_dof;
145 else GMM_ASSERT1(
false,
"Wrong convex number: " << cv);
148 size_type interpolated_fem::index_of_global_dof
150 {
return elements[cv].inddof[i]; }
162 else GMM_ASSERT1(
false,
"Wrong convex number: " << cv);
166 { GMM_ASSERT1(
false,
"No base values, real only element."); }
169 { GMM_ASSERT1(
false,
"No grad values, real only element."); }
172 { GMM_ASSERT1(
false,
"No hess values, real only element."); }
174 inline void interpolated_fem::actualize_fictx(
pfem pf,
size_type cv,
175 const base_node &ptr)
const {
176 if (fictx_cv != cv) {
179 (mf.
linked_mesh().trans_of_convex(cv), pf, base_node(), G, cv,
187 base_tensor &t,
bool)
const {
188 elt_interpolation_data &e = elements.at(c.
convex_num());
193 std::fill(t.begin(), t.end(), scalar_type(0));
194 if (e.nb_dof == 0)
return;
197 (c.pgp()->get_ppoint_tab()
198 == e.pim->approx_method()->pintegration_points())) {
199 gausspt_interpolation_data &gpid = e.gausspt.at(c.ii());
200 if (gpid.iflags & 1) {
203 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
204 if (gpid.iflags & 2) { t = gpid.base_val;
return; }
205 actualize_fictx(pf, cv, gpid.ptref);
206 pf->real_base_value(fictx, taux);
207 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
208 if (gpid.local_dof[i*rdim] !=
size_type(-1))
210 t(gpid.local_dof[i*rdim+j*mdim],j) = taux(i, j*(1-mdim));
211 if (store_values) { gpid.base_val = t; gpid.iflags |= 2; }
215 if (find_a_point(c.
xreal(), ptref, cv)) {
217 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
218 actualize_fictx(pf, cv, ptref);
219 pf->real_base_value(fictx, taux);
220 for (
size_type i = 0; i < e.nb_dof; ++i) {
221 ind_dof.at(e.inddof[i]) = i;
223 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
228 = taux(i, j*(1-mdim));
240 elt_interpolation_data &e = elements.at(c.
convex_num());
245 std::fill(t.begin(), t.end(), scalar_type(0));
246 if (nbdof == 0)
return;
249 (c.pgp()->get_ppoint_tab()
250 == e.pim->approx_method()->pintegration_points())) {
251 gausspt_interpolation_data &gpid = e.gausspt.at(c.ii());
252 if (gpid.iflags & 1) {
255 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
256 if (gpid.iflags & 4) { t = gpid.grad_val;
return; }
257 actualize_fictx(pf, cv, gpid.ptref);
258 pf->real_grad_base_value(fictx, taux);
261 pif->grad(c.
xreal(), trans);
262 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
263 if (gpid.local_dof[i*rdim] !=
size_type(-1))
268 ee += trans(l, k) * taux(i, j*(1-mdim), l);
269 t(gpid.local_dof[i*rdim+j*mdim], j, k) = ee;
273 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
274 if (gpid.local_dof[i*rdim] !=
size_type(-1))
277 t(gpid.local_dof[i*rdim+j*mdim], j, k)
278 = taux(i, j*(1-mdim), k);
279 if (store_values) { gpid.grad_val = t; gpid.iflags |= 4; }
284 cerr <<
"NON PGP OU MAUVAIS PTS sz=" << elements.size() <<
", cv="
286 cerr <<
"ii=" << c.ii() <<
", sz=" << e.gausspt.size() <<
"\n";
288 if (find_a_point(c.
xreal(), ptref, cv)) {
290 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
291 actualize_fictx(pf, cv, ptref);
292 pf->real_grad_base_value(fictx, taux);
294 ind_dof.at(e.inddof.at(i)) = i;
296 pif->grad(c.
xreal(), trans);
297 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
304 ee += trans(l, k) * taux(i, j*(1-mdim), l);
309 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
315 = taux(i,j*(1-mdim),k);
325 { GMM_ASSERT1(
false,
"Sorry, to be done."); }
332 for (
unsigned ii=0; ii < elements.at(cv).gausspt.size(); ++ii) {
333 if (elements[cv].gausspt[ii].iflags)
334 bv.add(elements[cv].gausspt[ii].elt);
341 scalar_type &meang)
const {
344 !cv.finished(); ++cv) {
345 for (
unsigned ii=0; ii < elements.at(cv).gausspt.size(); ++ii) {
346 if (elements[cv].gausspt[ii].iflags)
347 v[elements[cv].gausspt[ii].elt]++;
350 ming = 100000; maxg = 0; meang = 0;
352 !cv.finished(); ++cv) {
353 ming = std::min(ming, v[cv]);
354 maxg = std::max(maxg, v[cv]);
360 size_type interpolated_fem::memsize()
const {
362 sz += blocked_dof.memsize();
364 sz += elements.capacity() *
sizeof(elt_interpolation_data);
365 for (
unsigned i=0; i < elements.size(); ++i) {
366 sz += elements[i].gausspt.capacity()*
sizeof(gausspt_interpolation_data);
367 sz += elements[i].inddof.capacity() *
sizeof(
size_type);
368 for (
unsigned j=0; j < elements[i].gausspt.size(); ++j) {
369 sz += elements[i].gausspt[j].local_dof.capacity() *
sizeof(
size_type);
375 interpolated_fem::interpolated_fem(
const mesh_fem &mef,
377 pinterpolated_func pif_,
378 dal::bit_vector blocked_dof_,
380 : mf(mef), mim(meim), pif(pif_), store_values(store_val),
381 blocked_dof(blocked_dof_), boxtree{1E-13}, mi2(2), mi3(3) {
382 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"Interpolated fem");
383 this->add_dependency(mf);
384 this->add_dependency(mim);
385 is_pol = is_lag = is_standard_fem =
false; es_degree = 5;
386 is_equiv = real_element_defined =
true;
388 ntarget_dim = mef.get_qdim();
392 DAL_SIMPLE_KEY(special_intfem_key,
pfem);
395 pinterpolated_func pif,
396 dal::bit_vector blocked_dof,
bool store_val) {
397 pfem pf = std::make_shared<interpolated_fem>
398 (mef, mim, pif, blocked_dof, store_val);
399 dal::pstatic_stored_object_key pk=std::make_shared<special_intfem_key>(pf);
const base_node & xreal() const
coordinates of the current point, in the real convex.
void set_xref(const base_node &P)
change the current point (coordinates given in the reference convex)
does the inversion of the geometric transformation for a given convex
bool invert(const base_node &n, base_node &n_ref, scalar_type IN_EPS=1e-12, bool project_into_element=false)
given the node on the real element, returns the node on the reference element (even if it is outside ...
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
size_type nb_allocated_convex() const
The number of convex indexes from 0 to the index of the last convex.
bool context_check() const
return true if update_from_context was called
structure passed as the argument of fem interpolation functions.
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...
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_...
void grad_base_value(const base_node &, base_tensor &) const
Give the value of all gradients (on ref.
virtual size_type nb_dof(size_type cv) const
Number of degrees of freedom.
virtual void update_from_context(void) const
this function has to be defined and should update the object when the context is modified.
virtual const bgeot::convex< base_node > & node_convex(size_type cv) const
Gives the convex representing the nodes on the reference element.
void hess_base_value(const base_node &, base_tensor &) const
Give the value of all hessians (on ref.
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 gauss_pts_stats(unsigned &ming, unsigned &maxg, scalar_type &meang) const
return the min/max/mean number of gauss points in the convexes of the interpolated mesh_fem
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...
dal::bit_vector interpolated_convexes() const
return the list of convexes of the interpolated mesh_fem which contain at least one gauss point (shou...
virtual bgeot::pconvex_ref ref_convex(size_type cv) const
Return the convex of the reference element.
Describe a finite element method linked to a mesh.
virtual ind_dof_ct ind_basic_dof_of_element(size_type cv) const
Give an array of the dof numbers a of convex.
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
virtual size_type nb_basic_dof() const
Return the total number of basic degrees of freedom (before the optional reduction).
virtual pfem fem_of_element(size_type cv) const
Return the basic fem associated with an element (if no fem is associated, the function will crash!...
const dal::bit_vector & convex_index() const
Get the set of convexes where a finite element has been assigned.
virtual size_type nb_basic_dof_of_element(size_type cv) const
Return the number of degrees of freedom attached to a given convex.
bool is_reduced() const
Return true if a reduction matrix is applied to the dofs.
Describe an integration method linked to a mesh.
virtual pintegration_method int_method_of_element(size_type cv) const
return the integration method associated with an element (in no integration is associated,...
const mesh & linked_mesh() const
Give a reference to the linked mesh of type mesh.
const dal::bit_vector & convex_index(void) const
Get the set of convexes where an integration method has been assigned.
ref_convex convex(size_type ic) const
return a bgeot::convex object for the convex number ic.
FEM which interpolates a mesh_fem on a different mesh.
void resize(V &v, size_type n)
*/
pdof_description global_dof(dim_type d)
Description of a global dof, i.e.
dim_type target_dim() const
dimension of the target space.
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
dim_type dim() const
dimension of the reference element.
gmm::uint16_type short_type
used as the common short type integer in the library
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
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
GEneric Tool for Finite Element Methods.
pfem new_interpolated_fem(const mesh_fem &mef, const mesh_im &mim, pinterpolated_func pif=0, dal::bit_vector blocked_dof=dal::bit_vector(), bool store_val=true)
create a new interpolated FEM.