38 #ifndef GETFEM_INTERPOLATION_H__
39 #define GETFEM_INTERPOLATION_H__
59 std::vector<std::set<size_type> > pts_in_cvx;
60 std::vector<base_node> ref_coords;
62 std::map<size_type,size_type> ids;
67 {
return pts_in_cvx[i].size(); }
68 void points_on_convex(
size_type i, std::vector<size_type> &itab)
const;
70 const std::vector<base_node> &reference_coords()
const {
return ref_coords; }
72 void add_point_with_id(base_node n,
size_type id)
75 const mesh &linked_mesh()
const {
return msh; }
87 void distribute(
int extrapolation = 0,
89 mesh_trans_inv(
const mesh &m,
double EPS_ = 1E-12)
90 :
bgeot::geotrans_inv(EPS_), msh(m) {}
101 template <
typename VECT,
typename F,
typename M>
102 inline void interpolation_function__(
const mesh_fem &mf, VECT &V,
103 F &f,
const dal::bit_vector &dofs,
104 const M &, gmm::abstract_null_type) {
106 GMM_ASSERT1(gmm::vect_size(V) == mf.nb_basic_dof() && Q == 1,
107 "Dof vector has not the right size");
108 for (dal::bv_visitor i(dofs); !i.finished(); ++i)
109 V[i] = f(mf.point_of_basic_dof(i));
112 template <
typename VECT,
typename F,
typename M>
113 inline void interpolation_function__(
const mesh_fem &mf, VECT &V,
114 F &f,
const dal::bit_vector &dofs,
115 const M &v, gmm::abstract_vector) {
116 size_type N = gmm::vect_size(v), Q = mf.get_qdim();
117 GMM_ASSERT1(gmm::vect_size(V) == mf.nb_basic_dof()*N/Q,
118 "Dof vector has not the right size");
119 for (dal::bv_visitor i(dofs); !i.finished(); ++i)
122 gmm::sub_vector(V, gmm::sub_interval(i*N/Q, N)));
125 template <
typename VECT,
typename F,
typename M>
126 inline void interpolation_function__(
const mesh_fem &mf, VECT &V,
127 F &f,
const dal::bit_vector &dofs,
128 const M &mm, gmm::abstract_matrix) {
130 size_type Nr = gmm::mat_nrows(mm), Nc = gmm::mat_ncols(mm), N = Nr*Nc;
132 base_matrix m(Nr, Nc);
133 GMM_ASSERT1(gmm::vect_size(V) == mf.nb_basic_dof()*N/Q,
134 "Dof vector has not the right size");
135 for (dal::bv_visitor i(dofs); !i.finished(); ++i)
137 gmm::copy(f(mf.point_of_basic_dof(i)), m);
139 gmm::copy(gmm::mat_col(m, j),
140 gmm::sub_vector(V, gmm::sub_interval(i*N/Q+j*Nr, Nr)));
145 template <
typename VECT,
typename F,
typename M>
146 inline void interpolation_function_(
const mesh_fem &mf, VECT &V,
147 F &f,
const dal::bit_vector &dofs,
149 interpolation_function__(mf, V, f, dofs, m,
150 typename gmm::linalg_traits<M>::linalg_type());
153 #if GETFEM_PARA_LEVEL > 0
154 template <
typename T>
155 void take_one_op(
void *a,
void *b,
int *len, MPI_Datatype *) {
157 return aa ? aa : *((T*)b);
160 template <
typename T>
161 inline MPI_Op mpi_take_one_op(T) {
162 static bool isinit =
false;
165 MPI_Op_create(take_one_op<T>,
true, &op);
182 template <
typename VECT,
typename F>
185 typedef typename gmm::linalg_traits<VECT>::value_type T;
188 mf_target.
linked_mesh().intersect_with_mpi_region(rg);
191 interpolation_function_(mf_target, V, f, dofs,
200 gmm::sub_vector(
const_cast<VECT &
>(VV),
201 gmm::sub_slice(k, mf_target.
nb_dof(),
205 gmm::copy(V,
const_cast<VECT &
>(VV));
234 template<
typename VECTU,
typename VECTV>
235 void interpolation(
const mesh_fem &mf_source,
const mesh_fem &mf_target,
236 const VECTU &U, VECTV &V,
int extrapolation = 0,
253 template<
typename MAT>
254 void interpolation(
const mesh_fem &mf_source,
const mesh_fem &mf_target,
255 MAT &M,
int extrapolation = 0,
double EPS = 1E-10,
271 template<
typename VECTU,
typename VECTV,
typename MAT>
272 void interpolation_same_mesh(
const mesh_fem &mf_source,
273 const mesh_fem &mf_target,
274 const VECTU &UU, VECTV &VV,
275 MAT &MM,
int version) {
277 typedef typename gmm::linalg_traits<VECTU>::value_type T;
279 dim_type qdim = mf_source.get_qdim();
280 dim_type qqdim = dim_type(gmm::vect_size(UU)/mf_source.nb_dof());
281 std::vector<T> val(qdim);
282 std::vector<std::vector<T> > coeff;
283 std::vector<size_type> dof_source;
284 GMM_ASSERT1(qdim == mf_target.get_qdim() || mf_target.get_qdim() == 1,
285 "Attempt to interpolate a field of dimension "
286 << qdim <<
" on a mesh_fem whose Qdim is " <<
287 int(mf_target.get_qdim()));
288 size_type qmult = mf_source.get_qdim()/mf_target.get_qdim();
289 size_type qqdimt = qqdim * mf_source.get_qdim()/mf_target.get_qdim();
290 fem_precomp_pool fppool;
291 std::vector<size_type> dof_t_passes(mf_target.nb_basic_dof());
292 std::vector<T> U(mf_source.nb_basic_dof()*qqdim);
293 std::vector<T> V(mf_target.nb_basic_dof()*qqdimt);
294 gmm::row_matrix<gmm::rsvector<scalar_type> >
295 M(mf_target.nb_basic_dof(), mf_source.nb_basic_dof());
297 if (version == 0) mf_source.extend_vector(UU, U);
300 for (dal::bv_visitor cv(mf_source.convex_index()); !cv.finished(); ++cv) {
302 pfem pf_s = mf_source.fem_of_element(cv);
303 if (!mf_target.convex_index().is_in(cv))
305 pfem pf_t = mf_target.fem_of_element(cv);
308 mesh_fem::ind_dof_ct::const_iterator itdof;
309 size_type cvnbdof = mf_source.nb_basic_dof_of_element(cv);
311 bool discontinuous_source =
false;
312 for (
size_type dof=0; dof < nbd_s; ++dof)
314 discontinuous_source =
true;
321 coeff[qq].resize(cvnbdof);
322 itdof = mf_source.ind_basic_dof_of_element(cv).begin();
323 for (
size_type k = 0; k < cvnbdof; ++k, ++itdof) {
324 coeff[qq][k] = U[(*itdof)*qqdim+qq];
329 bgeot::vectors_to_base_matrix
330 (G, mf_source.linked_mesh().points_of_convex(cv));
332 GMM_ASSERT1(pf_t->target_dim() == 1,
333 "won't interpolate on a vector FEM... ");
334 pfem_precomp pfp = fppool(pf_s, pf_t->node_tab(cv));
335 fem_interpolation_context ctx(pgt,pfp,
size_type(-1), G, cv,
337 itdof = mf_target.ind_basic_dof_of_element(cv).begin();
339 const mesh_fem::ind_dof_ct &idct
340 = mf_source.ind_basic_dof_of_element(cv);
341 dof_source.assign(idct.begin(), idct.end());
343 for (
size_type i = 0; i < nbd_t; ++i, itdof+=mf_target.get_qdim()) {
345 if (!discontinuous_source && dof_t_passes[*itdof] > 0)
continue;
346 dof_t_passes[*itdof] += 1;
350 pf_s->interpolation(ctx, coeff[qq], val, qdim);
352 V[(dof_t + k)*qqdim+qq] += val[k];
356 base_matrix Mloc(qdim, mf_source.nb_basic_dof_of_element(cv));
357 pf_s->interpolation(ctx, Mloc, qdim);
359 for (
size_type j=0; j < dof_source.size(); ++j) {
360 M(dof_t + k, dof_source[j]) += Mloc(k, j);
368 for (
size_type i = 0; i < mf_target.nb_basic_dof(); ++i) {
370 scalar_type passes = scalar_type(dof_t_passes[i]);
371 if (version == 0 && passes > scalar_type(0))
374 V[(dof_t + k)*qqdim+qq] /= passes;
375 else if (passes > scalar_type(0))
377 for (
size_type j=0; j < dof_source.size(); ++j)
378 gmm::scale(gmm::mat_row(M, dof_t + k), scalar_type(1)/passes);
382 mf_target.reduce_vector(V, VV);
384 if (mf_target.is_reduced())
385 if (mf_source.is_reduced()) {
386 gmm::row_matrix<gmm::rsvector<scalar_type> >
387 MMM(mf_target.nb_dof(), mf_source.nb_basic_dof());
388 gmm::mult(mf_target.reduction_matrix(), M, MMM);
389 gmm::mult(MMM, mf_source.extension_matrix(), MM);
392 gmm::mult(mf_target.reduction_matrix(), M, MM);
394 if (mf_source.is_reduced())
395 gmm::mult(M, mf_source.extension_matrix(), MM);
407 template<
typename VECTU,
typename VECTV,
typename MAT>
410 const VECTU &UU, VECTV &V, MAT &MM,
411 int version,
int extrapolation = 0,
412 dal::bit_vector *dof_untouched = 0,
415 typedef typename gmm::linalg_traits<VECTU>::value_type T;
416 const mesh &msh(mf_source.linked_mesh());
417 dim_type qdim_s = mf_source.get_qdim();
418 dim_type qqdim = dim_type(gmm::vect_size(UU)/mf_source.nb_dof());
420 std::vector<T> U(mf_source.nb_basic_dof()*qqdim);
421 gmm::row_matrix<gmm::rsvector<scalar_type> > M;
422 if (version != 0) M.resize(gmm::mat_nrows(MM), mf_source.nb_basic_dof());
424 if (version == 0) mf_source.extend_vector(UU, U);
426 mti.distribute(extrapolation, rg_source);
427 std::vector<size_type> itab;
431 dal::bit_vector points_to_do; points_to_do.add(0, mti.nb_points());
432 std::vector<T> val(qdim_s);
433 std::vector<std::vector<T> > coeff;
435 std::vector<size_type> dof_source;
437 for (dal::bv_visitor cv(mf_source.convex_index()); !cv.finished(); ++cv) {
439 mti.points_on_convex(cv, itab);
440 if (itab.size() == 0)
continue;
442 pfem pf_s = mf_source.fem_of_element(cv);
444 bgeot::vectors_to_base_matrix(G, msh.points_of_convex(cv));
446 fem_interpolation_context ctx(pgt, pf_s, base_node(), G, cv,
450 size_type cvnbdof = mf_source.nb_basic_dof_of_element(cv);
451 mesh_fem::ind_dof_ct::const_iterator itdof;
453 coeff[qq].resize(cvnbdof);
454 itdof = mf_source.ind_basic_dof_of_element(cv).begin();
455 for (
size_type k = 0; k < cvnbdof; ++k, ++itdof) {
456 coeff[qq][k] = U[(*itdof)*qqdim+qq];
461 const mesh_fem::ind_dof_ct &idct
462 = mf_source.ind_basic_dof_of_element(cv);
463 dof_source.assign(idct.begin(), idct.end());
465 for (
size_type i = 0; i < itab.size(); ++i) {
467 if (points_to_do.is_in(ipt)) {
468 points_to_do.sup(ipt);
469 ctx.set_xref(mti.reference_coords()[ipt]);
474 pf_s->interpolation(ctx, coeff[qq], val, qdim_s);
476 V[(pos + k)*qqdim+qq] = val[k];
486 base_matrix Mloc(qdim_s, mf_source.nb_basic_dof_of_element(cv));
487 pf_s->interpolation(ctx, Mloc, qdim_s);
489 for (
size_type j=0; j < gmm::mat_ncols(Mloc); ++j)
490 M(pos+k, dof_source[j]) = Mloc(k,j);
501 if (points_to_do.card() != 0) {
503 dof_untouched->clear();
504 for (dal::bv_visitor ipt(points_to_do); !ipt.finished(); ++ipt)
505 dof_untouched->add(mti.id_of_point(ipt));
508 dal::bit_vector dofs_to_do;
509 for (dal::bv_visitor ipt(points_to_do); !ipt.finished(); ++ipt)
510 dofs_to_do.add(mti.id_of_point(ipt));
511 GMM_WARNING2(
"in interpolation (different meshes),"
512 << dofs_to_do.card() <<
" dof of target mesh_fem have "
513 <<
" been missed\nmissing dofs : " << dofs_to_do);
518 if (mf_source.is_reduced())
519 gmm::mult(M, mf_source.extension_matrix(), MM);
526 template<
typename VECTU,
typename VECTV>
527 void interpolation(
const mesh_fem &mf_source, mesh_trans_inv &mti,
528 const VECTU &U, VECTV &V,
int extrapolation = 0,
529 dal::bit_vector *dof_untouched = 0,
532 GMM_ASSERT1((gmm::vect_size(U) % mf_source.nb_dof()) == 0 &&
533 gmm::vect_size(V)!=0,
"Dimension of vector mismatch");
534 interpolation(mf_source, mti, U, V, M, 0, extrapolation, dof_untouched, rg_source);
544 template<
typename VECTU,
typename VECTV,
typename MAT>
545 void interpolation(
const mesh_fem &mf_source,
const mesh_fem &mf_target,
546 const VECTU &U, VECTV &VV, MAT &MM,
547 int version,
int extrapolation,
553 const torus_mesh_fem * pmf_torus =
dynamic_cast<const torus_mesh_fem *
>(&mf_target);
555 interpolation_to_torus_mesh_fem(mf_source, *pmf_torus,
556 U, VV, MM, version, extrapolation, EPS, rg_source, rg_target);
560 typedef typename gmm::linalg_traits<VECTU>::value_type T;
561 dim_type qqdim = dim_type(gmm::vect_size(U)/mf_source.nb_dof());
562 size_type qqdimt = qqdim * mf_source.get_qdim()/mf_target.get_qdim();
563 std::vector<T> V(mf_target.nb_basic_dof()*qqdimt);
564 mf_target.extend_vector(VV,V);
565 gmm::row_matrix<gmm::rsvector<scalar_type> > M;
566 if (version != 0) M.resize(mf_target.nb_basic_dof(), mf_source.nb_dof());
568 const mesh &msh(mf_source.linked_mesh());
569 getfem::mesh_trans_inv mti(msh, EPS);
570 size_type qdim_s = mf_source.get_qdim(), qdim_t = mf_target.get_qdim();
571 GMM_ASSERT1(qdim_s == qdim_t || qdim_t == 1,
572 "Attempt to interpolate a field of dimension "
573 << qdim_s <<
" on a mesh_fem whose Qdim is " << qdim_t);
576 for (dal::bv_visitor cv(mf_target.convex_index()); !cv.finished();++cv) {
577 pfem pf_t = mf_target.fem_of_element(cv);
578 GMM_ASSERT1(pf_t->target_dim() == 1 && pf_t->is_lagrange(),
579 "Target fem not convenient for interpolation");
582 bool is_target_torus =
dynamic_cast<const torus_mesh *
>(&mf_target.linked_mesh());
584 size_type nbpts = mf_target.nb_basic_dof() / qdim_t;
586 if (is_target_torus){
587 auto p = mf_target.point_of_basic_dof(i * qdim_t);
591 else mti.add_point(mf_target.point_of_basic_dof(i * qdim_t));
595 for (dal::bv_visitor_c dof(mf_target.basic_dof_on_region(rg_target));
596 !dof.finished(); ++dof)
597 if (dof % qdim_t == 0){
598 if (is_target_torus){
599 auto p = mf_target.point_of_basic_dof(dof);
601 mti.add_point_with_id(p, dof/qdim_t);
604 mti.add_point_with_id(mf_target.point_of_basic_dof(dof),dof/qdim_t);
607 interpolation(mf_source, mti, U, V, M, version, extrapolation, 0,rg_source);
610 mf_target.reduce_vector(V, VV);
612 if (mf_target.is_reduced())
613 gmm::mult(mf_target.reduction_matrix(), M, MM);
624 template<
typename VECTU,
typename VECTV,
typename MAT>
625 void interpolation_to_torus_mesh_fem(
const mesh_fem &mf_source,
const torus_mesh_fem &mf_target,
626 const VECTU &U, VECTV &VV, MAT &MM,
627 int version,
int extrapolation,
632 typedef typename gmm::linalg_traits<VECTU>::value_type T;
633 dim_type qqdim = dim_type(gmm::vect_size(U)/mf_source.nb_dof());
634 size_type qqdimt = qqdim * mf_source.get_qdim()/mf_target.get_qdim();
635 std::vector<T> V(mf_target.nb_basic_dof()*qqdimt);
636 mf_target.extend_vector(VV,V);
637 gmm::row_matrix<gmm::rsvector<scalar_type> >
638 M(mf_target.nb_basic_dof(), mf_source.nb_dof());
640 const mesh &msh(mf_source.linked_mesh());
641 getfem::mesh_trans_inv mti(msh, EPS);
642 size_type qdim_s = mf_source.get_qdim(), qdim_t = mf_target.get_qdim();
643 GMM_ASSERT1(qdim_s == qdim_t || qdim_t == 1,
644 "Attempt to interpolate a field of dimension "
645 << qdim_s <<
" on a mesh_fem whose Qdim is " << qdim_t);
648 for (dal::bv_visitor cv(mf_target.convex_index()); !cv.finished();++cv) {
649 pfem pf_t = mf_target.fem_of_element(cv);
651 GMM_ASSERT1(pf_t->target_dim() == 1 ||
652 (mf_target.get_qdim() == mf_target.linked_mesh().dim()),
653 "Target fem not convenient for interpolation");
657 size_type nbpts = mf_target.nb_basic_dof() / qdim_t;
660 base_node p(msh.dim());
661 for (
size_type k=0; k < msh.dim(); ++k) p[k] = mf_target.point_of_basic_dof(i * qdim_t)[k];
664 interpolation(mf_source, mti, U, V, M, version, extrapolation);
667 for (dal::bv_visitor_c dof(mf_target.basic_dof_on_region(rg_target)); !dof.finished(); ++dof)
668 if (dof % qdim_t == 0)
670 base_node p(msh.dim());
671 for (
size_type k=0; k < msh.dim(); ++k) p[k] = mf_target.point_of_basic_dof(dof)[k];
672 mti.add_point_with_id(p, dof/qdim_t);
674 interpolation(mf_source, mti, U, V, M, version, extrapolation, 0, rg_source);
678 mf_target.reduce_vector(V, VV);
680 if (mf_target.is_reduced())
681 gmm::mult(mf_target.reduction_matrix(), M, MM);
689 template<
typename VECTU,
typename VECTV>
691 const VECTU &U, VECTV &V,
int extrapolation,
695 GMM_ASSERT1((gmm::vect_size(U) % mf_source.
nb_dof()) == 0
696 && (gmm::vect_size(V) % mf_target.
nb_dof()) == 0
697 && gmm::vect_size(V) != 0,
"Dimensions mismatch");
701 interpolation_same_mesh(mf_source, mf_target, U, V, M, 0);
704 auto partitioning_allowed = rg_source.is_partitioning_allowed();
707 auto &V_thrd = V_distributed.thrd_cast();
708 gmm::resize(V_thrd, V.size());
710 mf_source, mf_target, U, V_thrd, M, 0, extrapolation, EPS,
711 rg_source, rg_target);
713 for (
size_type thread=0; thread != V_distributed.num_threads(); ++thread){
714 auto &V_thrd2 = V_distributed(thread);
715 for (
size_type i = 0; i < V_thrd2.size(); ++i) {
716 if (gmm::abs(V_thrd2[i]) > EPS) V[i] = V_thrd2[i];
723 template<
typename MAT>
725 MAT &M,
int extrapolation,
double EPS,
727 GMM_ASSERT1(mf_source.
nb_dof() == gmm::mat_ncols(M)
728 && (gmm::mat_nrows(M) % mf_target.
nb_dof()) == 0
729 && gmm::mat_nrows(M) != 0,
"Dimensions mismatch");
730 std::vector<scalar_type> U, V;
734 interpolation_same_mesh(mf_source, mf_target, U, V, M, 1);
736 interpolation(mf_source, mf_target, U, V, M, 1, extrapolation, EPS,
737 rg_source, rg_target);
748 template <
typename VECT>
750 const VECT &nodal_data, VECT &int_pt_data,
751 bool use_im_data_filter =
true) {
754 dim_type qdim = mf_source.
get_qdim();
757 size_type nodal_data_size = gmm::vect_size(nodal_data);
758 dim_type data_qdim = nodal_data_size / nb_dof;
760 GMM_ASSERT1(data_qdim * mf_source.
nb_dof() == nodal_data_size,
761 "Incompatible size of mesh fem " << mf_source.
nb_dof() * data_qdim <<
762 " with the data " << nodal_data_size);
765 "Incompatible size of qdim for mesh_fem " << qdim
768 "mf_source and im_data do not share the same mesh.");
770 GMM_ASSERT1(nb_dof * data_qdim == nodal_data_size,
771 "Provided nodal data size is " << nodal_data_size
772 <<
" but expecting vector size of " << nb_dof);
776 GMM_ASSERT1(size_im_data == gmm::vect_size(int_pt_data),
777 "Provided im data size is " << gmm::vect_size(int_pt_data)
778 <<
" but expecting vector size of " << size_im_data);
780 VECT extended_nodal_data_((nb_dof != nb_basic_dof) ? nb_basic_dof * data_qdim : 0);
781 if (nb_dof != nb_basic_dof)
782 mf_source.extend_vector(nodal_data, extended_nodal_data_);
783 const VECT &extended_nodal_data = (nb_dof == nb_basic_dof) ? nodal_data : extended_nodal_data_;
785 dal::bit_vector im_data_convex_index(im_target.
convex_index(use_im_data_filter));
789 bgeot::base_tensor tensor_int_point(im_target.tensor_size());
791 for (dal::bv_visitor cv(im_data_convex_index); !cv.finished(); ++cv) {
795 if (pf_source == NULL)
798 mesh_fem::ind_dof_ct::const_iterator it_dof;
800 size_type nb_nodal_pt = cv_nb_dof / qdim;
801 coeff.resize(cv_nb_dof);
804 const getfem::papprox_integration pim(im_target.approx_int_method_of_element(cv));
805 if (pf_source->need_G())
806 bgeot::vectors_to_base_matrix(G, *(pim->pintegration_points()));
808 pfem_precomp pfp = fppool(pf_source, pim->pintegration_points());
817 for (
size_type i = 0; i < nb_int_pts; ++i, ++int_pt_id) {
819 ctx.
pf()->interpolation(ctx, coeff, tensor_int_point.as_vector(), qdim * data_qdim);
820 im_target.
set_tensor(int_pt_data, int_pt_id, tensor_int_point);
831 size_type i0 = pim->ind_first_point_on_face(f);
832 for (
size_type i = 0; i < nb_int_pts; ++i, ++int_pt_id) {
834 ctx.
pf()->interpolation(ctx, coeff, tensor_int_point.as_vector(), qdim * data_qdim);
835 im_target.
set_tensor(int_pt_data, int_pt_id, tensor_int_point);
void set_ii(size_type ii__)
change the current point (assuming a geotrans_precomp_ is used)
handles the geometric inversion for a given (supposedly quite large) set of points
size_type add_point(base_node p)
Add point p to the list of points.
structure passed as the argument of fem interpolation functions.
im_data provides indexing to the integration points of a mesh im object.
const mesh & linked_mesh() const
linked mesh
void set_tensor(VECT &V1, size_type cv, size_type i, const TENSOR &T, bool use_filter=true) const
set a tensor of an integration point from a raw vector data, described by the tensor size.
size_type nb_points_of_element(size_type cv, bool use_filter=false) const
Total number of points in element cv.
size_type nb_index(bool use_filter=false) const
Total numbers of index (integration points)
short_type nb_faces_of_element(size_type cv) const
Number of (active) faces in element cv.
size_type index_of_first_point(size_type cv, short_type f=short_type(-1), bool use_filter=false) const
Returns the index of the first integration point with no filtering.
size_type nb_tensor_elem() const
sum of tensor elements, M(3,3) will have 3*3=9 elements
dal::bit_vector convex_index(bool use_filter=false) const
List of convexes.
Describe a finite element method linked to a mesh.
virtual dim_type get_qdim() const
Return the Q dimension.
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
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 dal::bit_vector basic_dof_on_region(const mesh_region &b) const
Get a list of basic dof lying on a given mesh_region.
const REDUCTION_MATRIX & reduction_matrix() const
Return the reduction matrix applied to the dofs.
virtual base_node point_of_basic_dof(size_type cv, size_type i) const
Return the geometrical location of a degree 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!...
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.
structure used to hold a set of convexes and/or convex faces.
void allow_partitioning()
In multithreaded part of the program makes only a partition of the region visible in the index() and ...
void prohibit_partitioning()
Disregard partitioning, which means being able to see the whole region in multithreaded code.
static mesh_region all_convexes()
provide a default value for the mesh_region parameters of assembly procedures etc.
Use this template class for any object you want to distribute to open_MP threads.
a balanced tree stored in a dal::dynamic_array
Provides indexing of integration points for mesh_im.
Define the getfem::mesh_fem class.
#define GETFEM_OMP_PARALLEL(body)
Organizes a proper parallel omp section:
Provides mesh and mesh fem of torus.
void copy(const L1 &l1, L2 &l2)
*/
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
bool dof_linkable(pdof_description)
Says if the dof is linkable.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
const pfem pf() const
get the current FEM descriptor
gmm::uint16_type short_type
used as the common short type integer in the library
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
GEneric Tool for Finite Element Methods.
void interpolation_function(mesh_fem &mf_target, const VECT &VV, F &f, mesh_region rg=mesh_region::all_convexes())
interpolation of a function f on mf_target.
void interpolation_to_im_data(const mesh_fem &mf_source, const im_data &im_target, const VECT &nodal_data, VECT &int_pt_data, bool use_im_data_filter=true)
Interpolate mesh_fem data to im_data.
void interpolation(const mesh_fem &mf_source, const mesh_fem &mf_target, const VECTU &U, VECTV &V, int extrapolation=0, double EPS=1E-10, mesh_region rg_source=mesh_region::all_convexes(), mesh_region rg_target=mesh_region::all_convexes())
interpolation/extrapolation of (mf_source, U) on mf_target.
void slice_vector_on_basic_dof_of_element(const mesh_fem &mf, const VEC1 &vec, size_type cv, VEC2 &coeff, size_type qmult1=size_type(-1), size_type qmult2=size_type(-1))
Given a mesh_fem.