26 void interpolated_fem::build_rtree(
void)
const {
28 scalar_type EPS=1E-13;
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 for (
unsigned k=0; k < min.size(); ++k) { min[k]-=EPS; max[k]+=EPS; }
34 boxtree.add_box(min, max, 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) {
51 cv_stored = (*it)->id;
52 if (gic.
invert(pt, ptr, gt_invertible)) {
53 cv = (*it)->id;
return true;
65 "Interpolated fem works only on non reduced mesh_fems");
67 std::vector<elt_interpolation_data> vv(mim.
convex_index().last_true() + 1);
71 dal::bit_vector alldofs;
74 for (dal::bv_visitor cv(mim.
convex_index()); !cv.finished(); ++cv) {
75 if (dim_ == dim_type(-1))
79 "Convexes of different dimension: to be done");
81 GMM_ASSERT1(pim->type() == IM_APPROX,
"You have to use approximated " 82 "integration to interpolate a fem");
83 papprox_integration pai = pim->approx_method();
85 elements[cv].gausspt.resize(pai->nb_points());
88 for (
size_type k = 0; k < pai->nb_points(); ++k) {
89 gausspt_interpolation_data &gpid = elements[cv].gausspt[k];
91 gpt = pgt->transform(pai->point(k),
93 gpid.iflags = find_a_point(gpt, gpid.ptref, gpid.elt) ? 1 : 0;
94 if (gpid.iflags && last_cv != gpid.elt) {
98 if (!(blocked_dof[idof])) dofs.add(idof);
103 elements[cv].nb_dof = dofs.card();
104 elements[cv].pim = pim;
105 max_dof = std::max(max_dof, dofs.card());
106 elements[cv].inddof.resize(dofs.card());
108 for (dal::bv_visitor idof(dofs); !idof.finished(); ++idof)
109 { elements[cv].inddof[cnt] = idof; ind_dof[idof] = cnt++; }
110 for (
size_type k = 0; k < pai->nb_points(); ++k) {
111 gausspt_interpolation_data &gpid = elements[cv].gausspt[k];
114 gpid.local_dof.resize(nbd);
117 gpid.local_dof[i] = dofs.is_in(ndof) ? ind_dof[ndof]
125 base_node P(
dim()); gmm::fill(P,1./20);
126 std::vector<base_node> node_tab_(max_dof, P);
127 pspt_override = bgeot::store_point_tab(node_tab_);
129 dof_types_.resize(max_dof);
130 std::fill(dof_types_.begin(), dof_types_.end(),
136 std::fill(ind_dof.begin(), ind_dof.end(),
size_type(-1));
142 return elements[cv].
nb_dof;
143 else GMM_ASSERT1(
false,
"Wrong convex number: " << cv);
146 size_type interpolated_fem::index_of_global_dof
148 {
return elements[cv].inddof[i]; }
160 else GMM_ASSERT1(
false,
"Wrong convex number: " << cv);
164 { GMM_ASSERT1(
false,
"No base values, real only element."); }
167 { GMM_ASSERT1(
false,
"No grad values, real only element."); }
170 { GMM_ASSERT1(
false,
"No hess values, real only element."); }
172 inline void interpolated_fem::actualize_fictx(
pfem pf,
size_type cv,
173 const base_node &ptr)
const {
174 if (fictx_cv != cv) {
177 (mf.
linked_mesh().trans_of_convex(cv), pf, base_node(), G, cv,
185 base_tensor &t,
bool)
const {
186 elt_interpolation_data &e = elements.at(c.
convex_num());
191 std::fill(t.begin(), t.end(), scalar_type(0));
192 if (e.nb_dof == 0)
return;
195 (c.pgp()->get_ppoint_tab()
196 == e.pim->approx_method()->pintegration_points())) {
197 gausspt_interpolation_data &gpid = e.gausspt.at(c.ii());
198 if (gpid.iflags & 1) {
201 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
202 if (gpid.iflags & 2) { t = gpid.base_val;
return; }
203 actualize_fictx(pf, cv, gpid.ptref);
204 pf->real_base_value(fictx, taux);
205 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
206 if (gpid.local_dof[i*rdim] !=
size_type(-1))
208 t(gpid.local_dof[i*rdim+j*mdim],j) = taux(i, j*(1-mdim));
209 if (store_values) { gpid.base_val = t; gpid.iflags |= 2; }
213 if (find_a_point(c.
xreal(), ptref, cv)) {
215 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
216 actualize_fictx(pf, cv, ptref);
217 pf->real_base_value(fictx, taux);
218 for (
size_type i = 0; i < e.nb_dof; ++i) {
219 ind_dof.at(e.inddof[i]) = i;
221 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
226 = taux(i, j*(1-mdim));
238 elt_interpolation_data &e = elements.at(c.
convex_num());
243 std::fill(t.begin(), t.end(), scalar_type(0));
244 if (nbdof == 0)
return;
247 (c.pgp()->get_ppoint_tab()
248 == e.pim->approx_method()->pintegration_points())) {
249 gausspt_interpolation_data &gpid = e.gausspt.at(c.ii());
250 if (gpid.iflags & 1) {
253 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
254 if (gpid.iflags & 4) { t = gpid.grad_val;
return; }
255 actualize_fictx(pf, cv, gpid.ptref);
256 pf->real_grad_base_value(fictx, taux);
259 pif->grad(c.
xreal(), trans);
260 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
261 if (gpid.local_dof[i*rdim] !=
size_type(-1))
266 ee += trans(l, k) * taux(i, j*(1-mdim), l);
267 t(gpid.local_dof[i*rdim+j*mdim], j, k) = ee;
271 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
272 if (gpid.local_dof[i*rdim] !=
size_type(-1))
275 t(gpid.local_dof[i*rdim+j*mdim], j, k)
276 = taux(i, j*(1-mdim), k);
277 if (store_values) { gpid.grad_val = t; gpid.iflags |= 4; }
282 cerr <<
"NON PGP OU MAUVAIS PTS sz=" << elements.size() <<
", cv=" 284 cerr <<
"ii=" << c.ii() <<
", sz=" << e.gausspt.size() <<
"\n";
286 if (find_a_point(c.
xreal(), ptref, cv)) {
288 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
289 actualize_fictx(pf, cv, ptref);
290 pf->real_grad_base_value(fictx, taux);
292 ind_dof.at(e.inddof.at(i)) = i;
294 pif->grad(c.
xreal(), trans);
295 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
302 ee += trans(l, k) * taux(i, j*(1-mdim), l);
307 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
313 = taux(i,j*(1-mdim),k);
323 { GMM_ASSERT1(
false,
"Sorry, to be done."); }
330 for (
unsigned ii=0; ii < elements.at(cv).gausspt.size(); ++ii) {
331 if (elements[cv].gausspt[ii].iflags)
332 bv.add(elements[cv].gausspt[ii].elt);
339 scalar_type &meang)
const {
342 !cv.finished(); ++cv) {
343 for (
unsigned ii=0; ii < elements.at(cv).gausspt.size(); ++ii) {
344 if (elements[cv].gausspt[ii].iflags)
345 v[elements[cv].gausspt[ii].elt]++;
348 ming = 100000; maxg = 0; meang = 0;
350 !cv.finished(); ++cv) {
351 ming = std::min(ming, v[cv]);
352 maxg = std::max(maxg, v[cv]);
358 size_type interpolated_fem::memsize()
const {
360 sz += blocked_dof.memsize();
362 sz += elements.capacity() *
sizeof(elt_interpolation_data);
363 for (
unsigned i=0; i < elements.size(); ++i) {
364 sz += elements[i].gausspt.capacity()*
sizeof(gausspt_interpolation_data);
365 sz += elements[i].inddof.capacity() *
sizeof(
size_type);
366 for (
unsigned j=0; j < elements[i].gausspt.size(); ++j) {
367 sz += elements[i].gausspt[j].local_dof.capacity() *
sizeof(
size_type);
373 interpolated_fem::interpolated_fem(
const mesh_fem &mef,
375 pinterpolated_func pif_,
376 dal::bit_vector blocked_dof_,
378 : mf(mef), mim(meim), pif(pif_), store_values(store_val),
379 blocked_dof(blocked_dof_), mi2(2), mi3(3) {
380 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"Interpolated fem");
381 this->add_dependency(mf);
382 this->add_dependency(mim);
383 is_pol = is_lag = is_standard_fem =
false; es_degree = 5;
384 is_equiv = real_element_defined =
true;
390 DAL_SIMPLE_KEY(special_intfem_key,
pfem);
393 pinterpolated_func pif,
394 dal::bit_vector blocked_dof,
bool store_val) {
395 pfem pf = std::make_shared<interpolated_fem>
396 (mef, mim, pif, blocked_dof, store_val);
397 dal::pstatic_stored_object_key pk=std::make_shared<special_intfem_key>(pf);
virtual size_type nb_basic_dof_of_element(size_type cv) const
Return the number of degrees of freedom attached to a given convex.
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)
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_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_...
virtual const bgeot::convex< base_node > & node_convex(size_type cv) const
Gives the convex representing the nodes on the reference element.
size_type convex_num() const
get the current convex number
dim_type dim() const
dimension of the reference element.
virtual size_type nb_dof(size_type cv) const
Number of degrees of freedom.
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! us...
ref_convex convex(size_type ic) const
return a bgeot::convex object for the convex number ic.
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
does the inversion of the geometric transformation for a given convex
Describe an integration method linked to a mesh.
void grad_base_value(const base_node &, base_tensor &) const
Give the value of all gradients (on ref.
void hess_base_value(const base_node &, base_tensor &) const
Give the value of all hessians (on ref.
const base_node & xreal() const
coordinates of the current point, in the real convex.
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.
virtual size_type nb_basic_dof() const
Return the total number of basic degrees of freedom (before the optional reduction).
virtual dim_type get_qdim() const
Return the Q dimension.
bool invert(const base_node &n, base_node &n_ref, scalar_type IN_EPS=1e-12)
given the node on the real element, returns the node on the reference element (even if it is outside ...
structure passed as the argument of fem interpolation functions.
dim_type target_dim() const
dimension of the target space.
bool is_reduced() const
Return true if a reduction matrix is applied to the dofs.
GEneric Tool for Finite Element Methods.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Describe a finite element method linked to a mesh.
gmm::uint16_type short_type
used as the common short type integer in the library
size_type nb_allocated_convex() const
The number of convex indexes from 0 to the index of the last convex.
dal::bit_vector interpolated_convexes() const
return the list of convexes of the interpolated mesh_fem which contain at least one gauss point (shou...
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.
const dal::bit_vector & convex_index(void) const
Get the set of convexes where an integration method has been assigned.
virtual void update_from_context(void) const
this function has to be defined and should update the object when the context is modified.
FEM which interpolates a mesh_fem on a different mesh.
void set_xref(const base_node &P)
change the current point (coordinates given in the reference convex)
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
const mesh & linked_mesh() const
Give a reference to the linked mesh of type mesh.
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 bgeot::pconvex_ref ref_convex(size_type cv) const
Return the convex of the reference element.
const dal::bit_vector & convex_index() const
Get the set of convexes where a finite element has been assigned.
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...
pdof_description global_dof(dim_type d)
Description of a global dof, i.e.
virtual ind_dof_ct ind_basic_dof_of_element(size_type cv) const
Give an array of the dof numbers a of convex.
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
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...
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...