25 void interpolated_fem::build_rtree(
void)
const {
28 box_to_convexes_map.clear();
29 for (dal::bv_visitor cv(mf.
convex_index()); !cv.finished(); ++cv) {
30 bounding_box(min, max, mf.
linked_mesh().points_of_convex(cv),
32 box_to_convexes_map[boxtree.add_box(min, max, cv)].push_back(cv);
37 bool interpolated_fem::find_a_point(base_node pt, base_node &ptr,
40 if (pif) { base_node ptreal = pt; pif->val(ptreal, pt); }
42 { cv = cv_stored;
if (gt_invertible)
return true; }
43 boxtree.find_boxes_at_point(pt, boxlst);
44 bgeot::rtree::pbox_set::const_iterator it = boxlst.begin(),
46 for (; it != ite; ++it) {
47 for (
auto candidate : box_to_convexes_map.at((*it)->id)) {
51 cv_stored = candidate;
52 if (gic.
invert(pt, ptr, gt_invertible)) {
53 cv = candidate;
return true;
66 "Interpolated fem works only on non reduced mesh_fems");
68 std::vector<elt_interpolation_data> vv(mim.
convex_index().last_true() + 1);
72 dal::bit_vector alldofs;
75 for (dal::bv_visitor cv(mim.
convex_index()); !cv.finished(); ++cv) {
76 if (dim_ == dim_type(-1))
80 "Convexes of different dimension: to be done");
82 GMM_ASSERT1(pim->type() == IM_APPROX,
"You have to use approximated "
83 "integration to interpolate a fem");
84 papprox_integration pai = pim->approx_method();
86 elements[cv].gausspt.resize(pai->nb_points());
89 for (
size_type k = 0; k < pai->nb_points(); ++k) {
90 gausspt_interpolation_data &gpid = elements[cv].gausspt[k];
92 gpt = pgt->transform(pai->point(k),
94 gpid.iflags = find_a_point(gpt, gpid.ptref, gpid.elt) ? 1 : 0;
95 if (gpid.iflags && last_cv != gpid.elt) {
99 if (!(blocked_dof[idof])) dofs.add(idof);
104 elements[cv].nb_dof = dofs.card();
105 elements[cv].pim = pim;
106 max_dof = std::max(max_dof, dofs.card());
107 elements[cv].inddof.resize(dofs.card());
109 for (dal::bv_visitor idof(dofs); !idof.finished(); ++idof)
110 { elements[cv].inddof[cnt] = idof; ind_dof[idof] = cnt++; }
111 for (
size_type k = 0; k < pai->nb_points(); ++k) {
112 gausspt_interpolation_data &gpid = elements[cv].gausspt[k];
115 gpid.local_dof.resize(nbd);
118 gpid.local_dof[i] = dofs.is_in(ndof) ? ind_dof[ndof]
126 base_node P(
dim()); gmm::fill(P,1./20);
127 std::vector<base_node> node_tab_(max_dof, P);
128 pspt_override = bgeot::store_point_tab(node_tab_);
130 dof_types_.resize(max_dof);
131 std::fill(dof_types_.begin(), dof_types_.end(),
137 std::fill(ind_dof.begin(), ind_dof.end(),
size_type(-1));
143 return elements[cv].nb_dof;
144 else GMM_ASSERT1(
false,
"Wrong convex number: " << cv);
147 size_type interpolated_fem::index_of_global_dof
149 {
return elements[cv].inddof[i]; }
161 else GMM_ASSERT1(
false,
"Wrong convex number: " << cv);
165 { GMM_ASSERT1(
false,
"No base values, real only element."); }
168 { GMM_ASSERT1(
false,
"No grad values, real only element."); }
171 { GMM_ASSERT1(
false,
"No hess values, real only element."); }
173 inline void interpolated_fem::actualize_fictx(
pfem pf,
size_type cv,
174 const base_node &ptr)
const {
175 if (fictx_cv != cv) {
178 (mf.
linked_mesh().trans_of_convex(cv), pf, base_node(), G, cv,
186 base_tensor &t,
bool)
const {
187 elt_interpolation_data &e = elements.at(c.
convex_num());
192 std::fill(t.begin(), t.end(), scalar_type(0));
193 if (e.nb_dof == 0)
return;
196 (c.pgp()->get_ppoint_tab()
197 == e.pim->approx_method()->pintegration_points())) {
198 gausspt_interpolation_data &gpid = e.gausspt.at(c.ii());
199 if (gpid.iflags & 1) {
202 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
203 if (gpid.iflags & 2) { t = gpid.base_val;
return; }
204 actualize_fictx(pf, cv, gpid.ptref);
205 pf->real_base_value(fictx, taux);
206 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
207 if (gpid.local_dof[i*rdim] !=
size_type(-1))
209 t(gpid.local_dof[i*rdim+j*mdim],j) = taux(i, j*(1-mdim));
210 if (store_values) { gpid.base_val = t; gpid.iflags |= 2; }
214 if (find_a_point(c.
xreal(), ptref, cv)) {
216 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
217 actualize_fictx(pf, cv, ptref);
218 pf->real_base_value(fictx, taux);
219 for (
size_type i = 0; i < e.nb_dof; ++i) {
220 ind_dof.at(e.inddof[i]) = i;
222 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
227 = taux(i, j*(1-mdim));
239 elt_interpolation_data &e = elements.at(c.
convex_num());
244 std::fill(t.begin(), t.end(), scalar_type(0));
245 if (nbdof == 0)
return;
248 (c.pgp()->get_ppoint_tab()
249 == e.pim->approx_method()->pintegration_points())) {
250 gausspt_interpolation_data &gpid = e.gausspt.at(c.ii());
251 if (gpid.iflags & 1) {
254 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
255 if (gpid.iflags & 4) { t = gpid.grad_val;
return; }
256 actualize_fictx(pf, cv, gpid.ptref);
257 pf->real_grad_base_value(fictx, taux);
260 pif->grad(c.
xreal(), trans);
261 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
262 if (gpid.local_dof[i*rdim] !=
size_type(-1))
267 ee += trans(l, k) * taux(i, j*(1-mdim), l);
268 t(gpid.local_dof[i*rdim+j*mdim], j, k) = ee;
272 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
273 if (gpid.local_dof[i*rdim] !=
size_type(-1))
276 t(gpid.local_dof[i*rdim+j*mdim], j, k)
277 = taux(i, j*(1-mdim), k);
278 if (store_values) { gpid.grad_val = t; gpid.iflags |= 4; }
283 cerr <<
"NON PGP OU MAUVAIS PTS sz=" << elements.size() <<
", cv="
285 cerr <<
"ii=" << c.ii() <<
", sz=" << e.gausspt.size() <<
"\n";
287 if (find_a_point(c.
xreal(), ptref, cv)) {
289 unsigned rdim =
target_dim() / pf->target_dim(), mdim = (rdim==1) ? 0 : 1;
290 actualize_fictx(pf, cv, ptref);
291 pf->real_grad_base_value(fictx, taux);
293 ind_dof.at(e.inddof.at(i)) = i;
295 pif->grad(c.
xreal(), trans);
296 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
303 ee += trans(l, k) * taux(i, j*(1-mdim), l);
308 for (
size_type i = 0; i < pf->nb_dof(cv); ++i)
314 = taux(i,j*(1-mdim),k);
324 { GMM_ASSERT1(
false,
"Sorry, to be done."); }
331 for (
unsigned ii=0; ii < elements.at(cv).gausspt.size(); ++ii) {
332 if (elements[cv].gausspt[ii].iflags)
333 bv.add(elements[cv].gausspt[ii].elt);
340 scalar_type &meang)
const {
343 !cv.finished(); ++cv) {
344 for (
unsigned ii=0; ii < elements.at(cv).gausspt.size(); ++ii) {
345 if (elements[cv].gausspt[ii].iflags)
346 v[elements[cv].gausspt[ii].elt]++;
349 ming = 100000; maxg = 0; meang = 0;
351 !cv.finished(); ++cv) {
352 ming = std::min(ming, v[cv]);
353 maxg = std::max(maxg, v[cv]);
359 size_type interpolated_fem::memsize()
const {
361 sz += blocked_dof.memsize();
363 sz += elements.capacity() *
sizeof(elt_interpolation_data);
364 for (
unsigned i=0; i < elements.size(); ++i) {
365 sz += elements[i].gausspt.capacity()*
sizeof(gausspt_interpolation_data);
366 sz += elements[i].inddof.capacity() *
sizeof(
size_type);
367 for (
unsigned j=0; j < elements[i].gausspt.size(); ++j) {
368 sz += elements[i].gausspt[j].local_dof.capacity() *
sizeof(
size_type);
374 interpolated_fem::interpolated_fem(
const mesh_fem &mef,
376 pinterpolated_func pif_,
377 dal::bit_vector blocked_dof_,
379 : mf(mef), mim(meim), pif(pif_), store_values(store_val),
380 blocked_dof(blocked_dof_), boxtree{1E-13}, mi2(2), mi3(3) {
381 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"Interpolated fem");
382 this->add_dependency(mf);
383 this->add_dependency(mim);
384 is_pol = is_lag = is_standard_fem =
false; es_degree = 5;
385 is_equiv = real_element_defined =
true;
387 ntarget_dim = mef.get_qdim();
391 DAL_SIMPLE_KEY(special_intfem_key,
pfem);
394 pinterpolated_func pif,
395 dal::bit_vector blocked_dof,
bool store_val) {
396 pfem pf = std::make_shared<interpolated_fem>
397 (mef, mim, pif, blocked_dof, store_val);
398 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.