24 #include "getfem/getfem_generic_assembly_compile_and_exec.h" 
   25 #include "getfem/getfem_generic_assembly_functions_and_operators.h" 
   34   void ga_interpolation(ga_workspace &workspace,
 
   35                         ga_interpolation_context &gic) {
 
   36     ga_instruction_set gis;
 
   37     ga_compile_interpolation(workspace, gis);
 
   38     ga_interpolation_exec(gis, workspace, gic);
 
   42   struct ga_interpolation_context_fem_same_mesh
 
   43     : 
public ga_interpolation_context {
 
   45     std::vector<int> dof_count;
 
   51     virtual bgeot::pstored_point_tab
 
   53                        std::vector<size_type> &ind)
 const {
 
   54       pfem pf = mf.fem_of_element(cv);
 
   55       GMM_ASSERT1(pf->is_lagrange(),
 
   56                   "Only Lagrange fems can be used in interpolation");
 
   61              i < pf->node_convex(cv).structure()->nb_points_of_face(f); ++i)
 
   63             (pf->node_convex(cv).structure()->ind_points_of_face(f)[i]);
 
   65         for (
size_type i = 0; i < pf->node_convex(cv).nb_points(); ++i)
 
   69       return pf->node_tab(cv);
 
   72     virtual bool use_pgp(
size_type)
 const { 
return true; }
 
   73     virtual bool use_mim()
 const { 
return false; }
 
   85       size_type target_dim = mf.fem_of_element(cv)->target_dim();
 
   86       GMM_ASSERT2(target_dim == 3, 
"Invalid torus fem.");
 
   89       if (!initialized) {init_(qdim, qdim, qdim);}
 
   90       size_type idof = mf.ind_basic_dof_of_element(cv)[i];
 
   91       result[idof] = t[idof%result_dim];
 
   97         store_result_for_torus(cv, i, t);
 
  103       GMM_ASSERT1( (si % q) == 0, 
"Incompatibility between the mesh_fem and " 
  104                    "the size of the expression to be interpolated");
 
  105       if (!initialized) { init_(si, q, qmult); }
 
  106       GMM_ASSERT1(s == si, 
"Internal error");
 
  107       size_type idof = mf.ind_basic_dof_of_element(cv)[i*q];
 
  109                gmm::sub_vector(result, gmm::sub_interval(qmult*idof, s)));
 
  110       (dof_count[idof/q])++;
 
  113     virtual void finalize() {
 
  114       std::vector<size_type> data(3);
 
  115       data[0] = initialized ? result.size() : 0;
 
  116       data[1] = initialized ? dof_count.size() : 0;
 
  117       data[2] = initialized ? s : 0;
 
  118       MPI_MAX_VECTOR(data);
 
  129         GMM_ASSERT1(gmm::vect_size(result) == data[0] &&  s == data[2] &&
 
  130                   gmm::vect_size(dof_count) == data[1], 
"Incompatible sizes");
 
  131       MPI_SUM_VECTOR(result);
 
  132       MPI_SUM_VECTOR(dof_count);
 
  133       for (
size_type i = 0; i < dof_count.size(); ++i)
 
  135           gmm::scale(gmm::sub_vector(result, gmm::sub_interval(s*i, s)),
 
  136                      scalar_type(1) / scalar_type(dof_count[i]));
 
  139     virtual const mesh &linked_mesh() { 
return mf.linked_mesh(); }
 
  141     ga_interpolation_context_fem_same_mesh(
const mesh_fem &mf_, base_vector &r)
 
  142       : result(r), mf(mf_), initialized(false), is_torus(false) {
 
  143       GMM_ASSERT1(!(mf.is_reduced()),
 
  144                   "Interpolation on reduced fem is not allowed");
 
  145       if (
dynamic_cast<const torus_mesh_fem*
>(&mf)){
 
  146         auto first_cv = mf.first_convex_of_basic_dof(0);
 
  147         auto target_dim = mf.fem_of_element(first_cv)->target_dim();
 
  148         if (target_dim == 3) is_torus = 
true;
 
  153   void ga_interpolation_Lagrange_fem
 
  154   (ga_workspace &workspace, 
const mesh_fem &mf, base_vector &result) {
 
  155     ga_interpolation_context_fem_same_mesh gic(mf, result);
 
  156     ga_interpolation(workspace, gic);
 
  159   void ga_interpolation_Lagrange_fem
 
  160   (
const getfem::model &md, 
const std::string &expr, 
const mesh_fem &mf,
 
  161    base_vector &result, 
const mesh_region &rg) {
 
  162     ga_workspace workspace(md);
 
  163     workspace.add_interpolation_expression(expr, mf.linked_mesh(), rg);
 
  164     ga_interpolation_Lagrange_fem(workspace, mf, result);
 
  168   struct ga_interpolation_context_mti
 
  169     : 
public ga_interpolation_context {
 
  171     const mesh_trans_inv &mti;
 
  176     virtual bgeot::pstored_point_tab
 
  178                        std::vector<size_type> &ind)
 const {
 
  179       std::vector<size_type> itab;
 
  180       mti.points_on_convex(cv, itab);
 
  181       std::vector<base_node> pt_tab(itab.size());
 
  182       for (
size_type i = 0; i < itab.size(); ++i) {
 
  183         pt_tab[i] = mti.reference_coords()[itab[i]];
 
  186       return store_point_tab(pt_tab);
 
  189     virtual bool use_pgp(
size_type)
 const { 
return false; }
 
  190     virtual bool use_mim()
 const { 
return false; }
 
  200       GMM_ASSERT1(s == si, 
"Internal error");
 
  201       size_type ipt = mti.point_on_convex(cv, i);
 
  204                gmm::sub_vector(result, gmm::sub_interval(s*dof_t, s)));
 
  207     virtual void finalize() {
 
  208       std::vector<size_type> data(2);
 
  209       data[0] = initialized ? result.size() : 0;
 
  210       data[1] = initialized ? s : 0;
 
  211       MPI_MAX_VECTOR(data);
 
  220         GMM_ASSERT1(gmm::vect_size(result) == data[0] &&  s == data[1],
 
  221                     "Incompatible sizes");
 
  222       MPI_SUM_VECTOR(result);
 
  225     virtual const mesh &linked_mesh() { 
return mti.linked_mesh(); }
 
  227     ga_interpolation_context_mti(
const mesh_trans_inv &mti_, base_vector &r,
 
  229       : result(r), mti(mti_), initialized(false), nbdof(nbdof_) {
 
  230       if (nbdof == 
size_type(-1)) nbdof = mti.nb_points();
 
  235   void ga_interpolation_mti
 
  236   (
const getfem::model &md, 
const std::string &expr, mesh_trans_inv &mti,
 
  237    base_vector &result, 
const mesh_region &rg, 
int extrapolation,
 
  238    const mesh_region &rg_source, 
size_type nbdof) {
 
  240     ga_workspace workspace(md);
 
  241     workspace.add_interpolation_expression(expr, mti.linked_mesh(), rg);
 
  243     mti.distribute(extrapolation, rg_source);
 
  244     ga_interpolation_context_mti gic(mti, result, nbdof);
 
  245     ga_interpolation(workspace, gic);
 
  250   struct ga_interpolation_context_im_data
 
  251     : 
public ga_interpolation_context {
 
  257     virtual bgeot::pstored_point_tab
 
  259                         std::vector<size_type> &ind)
 const {
 
  260       pintegration_method pim =imd.linked_mesh_im().int_method_of_element(cv);
 
  261       if (pim->type() == IM_NONE) 
return bgeot::pstored_point_tab();
 
  262       GMM_ASSERT1(pim->type() == IM_APPROX, 
"Sorry, exact methods cannot " 
  263                   "be used in high level generic assembly");
 
  266         i_end = pim->approx_method()->nb_points_on_convex();
 
  268         i_start = pim->approx_method()->ind_first_point_on_face(f);
 
  269         i_end = i_start + pim->approx_method()->nb_points_on_face(f);
 
  271       for (
size_type i = i_start; i < i_end; ++i) ind.push_back(i);
 
  272       return pim->approx_method()->pintegration_points();
 
  275     virtual bool use_pgp(
size_type cv)
 const {
 
  276       pintegration_method pim =imd.linked_mesh_im().int_method_of_element(cv);
 
  277       if (pim->type() == IM_NONE) 
return false;
 
  278       GMM_ASSERT1(pim->type() == IM_APPROX, 
"Sorry, exact methods cannot " 
  279                   "be used in high level generic assembly");
 
  280       return !(pim->approx_method()->is_built_on_the_fly());
 
  282     virtual bool use_mim()
 const { 
return true; }
 
  288         GMM_ASSERT1(imd.tensor_size() == t.sizes() ||
 
  289                     (imd.tensor_size().size() == 
size_type(1) &&
 
  292                     "Im_data tensor size " << imd.tensor_size() <<
 
  293                     " does not match the size of the interpolated " 
  294                     "expression " << t.sizes() << 
".");
 
  299       GMM_ASSERT1(s == si, 
"Internal error");
 
  300       size_type ipt = imd.filtered_index_of_point(cv, i);
 
  302                   "Im data with no data on the current integration point.");
 
  304                gmm::sub_vector(result, gmm::sub_interval(s*ipt, s)));
 
  307     virtual void finalize() {
 
  308       std::vector<size_type> data(2);
 
  309       data[0] = initialized ? result.size() : 0;
 
  310       data[1] = initialized ? s : 0;
 
  311       MPI_MAX_VECTOR(data);
 
  313         GMM_ASSERT1(gmm::vect_size(result) == data[0] &&  s == data[1],
 
  314                     "Incompatible sizes");
 
  322       MPI_SUM_VECTOR(result);
 
  325     virtual const mesh &linked_mesh() { 
return imd.linked_mesh(); }
 
  327     ga_interpolation_context_im_data(
const im_data &imd_, base_vector &r)
 
  328       : result(r), imd(imd_), initialized(false) { }
 
  331   void ga_interpolation_im_data
 
  332   (ga_workspace &workspace, 
const im_data &imd, base_vector &result) {
 
  333     ga_interpolation_context_im_data gic(imd, result);
 
  334     ga_interpolation(workspace, gic);
 
  337   void ga_interpolation_im_data
 
  338   (
const getfem::model &md, 
const std::string &expr, 
const im_data &imd,
 
  339    base_vector &result, 
const mesh_region &rg) {
 
  340     ga_workspace workspace(md);
 
  341     workspace.add_interpolation_expression
 
  342       (expr, imd.linked_mesh_im(), rg);
 
  344     ga_interpolation_im_data(workspace, imd, result);
 
  349   struct ga_interpolation_context_mesh_slice
 
  350     : 
public ga_interpolation_context {
 
  352     const stored_mesh_slice &sl;
 
  355     std::vector<size_type> first_node;
 
  357     virtual bgeot::pstored_point_tab
 
  359                         std::vector<size_type> &ind)
 const {
 
  360       GMM_ASSERT1(f == 
short_type(-1), 
"No support for interpolation on faces" 
  361                                        " for a stored_mesh_slice yet.");
 
  363       const mesh_slicer::cs_nodes_ct &nodes = sl.nodes(ic);
 
  364       std::vector<base_node> pt_tab(nodes.size());
 
  365       for (
size_type i=0; i < nodes.size(); ++i) {
 
  366         pt_tab[i] = nodes[i].pt_ref;
 
  369       return store_point_tab(pt_tab);
 
  372     virtual bool use_pgp(
size_type )
 const { 
return false; } 
 
  373     virtual bool use_mim()
 const { 
return false; }
 
  382         first_node.resize(sl.nb_convex());
 
  383         for (
size_type ic=0; ic < sl.nb_convex()-1; ++ic)
 
  384           first_node[ic+1] = first_node[ic] + sl.nodes(ic).size();
 
  386       GMM_ASSERT1(s == si && result.size() == s * sl.nb_points(), 
"Internal error");
 
  390                gmm::sub_vector(result, gmm::sub_interval(s*ipt, s)));
 
  393     virtual void finalize() {
 
  394       std::vector<size_type> data(2);
 
  395       data[0] = initialized ? result.size() : 0;
 
  396       data[1] = initialized ? s : 0;
 
  397       MPI_MAX_VECTOR(data);
 
  399         GMM_ASSERT1(gmm::vect_size(result) == data[0] &&  s == data[1],
 
  400                     "Incompatible sizes");
 
  408       MPI_SUM_VECTOR(result);
 
  411     virtual const mesh &linked_mesh() { 
return sl.linked_mesh(); }
 
  413     ga_interpolation_context_mesh_slice(
const stored_mesh_slice &sl_,
 
  415       : result(r), sl(sl_), initialized(false) { }
 
  418   void ga_interpolation_mesh_slice
 
  419   (ga_workspace &workspace, 
const stored_mesh_slice &sl, base_vector &result) {
 
  420     ga_interpolation_context_mesh_slice gic(sl, result);
 
  421     ga_interpolation(workspace, gic);
 
  424   void ga_interpolation_mesh_slice
 
  425   (
const getfem::model &md, 
const std::string &expr, 
const stored_mesh_slice &sl,
 
  426    base_vector &result, 
const mesh_region &rg) {
 
  427     ga_workspace workspace(md);
 
  428     workspace.add_interpolation_expression(expr, sl.linked_mesh(), rg);
 
  429     ga_interpolation_mesh_slice(workspace, sl, result);
 
  438                            const std::string &expr, 
const mesh_fem &mf,
 
  447     model_real_sparse_matrix M(nbdof, nbdof);
 
  451     ga_workspace workspace(md, ga_workspace::inherit::NONE);
 
  452     gmm::sub_interval I(0,nbdof);
 
  453     workspace.add_fem_variable(
"c__dummy_var_95_", mf, I, base_vector(nbdof));
 
  454     if (mf.get_qdims().size() > 1)
 
  455       workspace.add_expression(
"("+expr+
"):Test_c__dummy_var_95_",mim,region,2);
 
  457       workspace.add_expression(
"("+expr+
").Test_c__dummy_var_95_",mim,region,2);
 
  458     getfem::base_vector F(nbdof);
 
  459     workspace.set_assembled_vector(F);
 
  460     workspace.assembly(1);
 
  461     gmm::resize(result, nbdof);
 
  463     getfem::base_matrix loc_M;
 
  464     getfem::base_vector loc_U;
 
  468         loc_M.base_resize(nd, nd); gmm::resize(loc_U, nd);
 
  470         gmm::copy(gmm::sub_matrix(M, J, J), loc_M);
 
  471         gmm::lu_solve(loc_M, loc_U, gmm::sub_vector(F, J));
 
  472         gmm::copy(loc_U, gmm::sub_vector(result, J));
 
  475     MPI_SUM_VECTOR(result);
 
  482   struct rated_box_index_compare {
 
  484       const std::pair<scalar_type, const bgeot::box_index*> &x,
 
  485       const std::pair<scalar_type, const bgeot::box_index*> &y)
 const {
 
  486       GMM_ASSERT2(x.second != 
nullptr, 
"x contains nullptr");
 
  487       GMM_ASSERT2(y.second != 
nullptr, 
"y contains nullptr");
 
  488       return (x.first < y.first) || (!(y.first < x.first) && (x.second->id < y.second->id));
 
  492   class interpolate_transformation_expression
 
  493     : 
public virtual_interpolate_transformation, 
public context_dependencies {
 
  495     struct workspace_gis_pair : 
public std::pair<ga_workspace, ga_instruction_set> {
 
  496       inline ga_workspace &workspace() { 
return this->first; }
 
  497       inline ga_instruction_set &gis() { 
return this->second; }
 
  500     const mesh &source_mesh;
 
  501     const mesh &target_mesh;
 
  505     mutable bool recompute_elt_boxes;
 
  506     mutable ga_workspace local_workspace;
 
  507     mutable ga_instruction_set local_gis;
 
  510     mutable std::set<var_trans_pair> used_vars;
 
  511     mutable std::set<var_trans_pair> used_data;
 
  512     mutable std::map<var_trans_pair,
 
  513                      workspace_gis_pair> compiled_derivatives;
 
  514     mutable bool extract_variable_done;
 
  515     mutable bool extract_data_done;
 
  518     mutable std::map<size_type, std::vector<size_type>> box_to_convexes;
 
  521     void update_from_context()
 const {
 
  522       recompute_elt_boxes = 
true;
 
  525     void extract_variables(
const ga_workspace &workspace,
 
  526                            std::set<var_trans_pair> &vars,
 
  527                            bool ignore_data, 
const mesh &,
 
  528                            const std::string &)
 const {
 
  529       if ((ignore_data && !extract_variable_done) ||
 
  530           (!ignore_data && !extract_data_done)) {
 
  535         ga_workspace aux_workspace(workspace, ga_workspace::inherit::ALL);
 
  536         aux_workspace.clear_expressions();
 
  537         aux_workspace.add_interpolation_expression(expr, source_mesh);
 
  538         for (
size_type i = 0; i < aux_workspace.nb_trees(); ++i)
 
  539           ga_extract_variables(aux_workspace.tree_info(i).ptree->root,
 
  540                                aux_workspace, source_mesh,
 
  541                                ignore_data ? used_vars : used_data,
 
  544           extract_variable_done = 
true;
 
  546           extract_data_done = 
true;
 
  549         vars.insert(used_vars.begin(), used_vars.end());
 
  551         vars.insert(used_data.begin(), used_data.end());
 
  554     void init(
const ga_workspace &workspace)
 const {
 
  558       local_workspace = ga_workspace(workspace, ga_workspace::inherit::ALL);
 
  559       local_workspace.clear_expressions();
 
  561       local_workspace.add_interpolation_expression(expr, source_mesh);
 
  562       local_gis = ga_instruction_set();
 
  563       ga_compile_interpolation(local_workspace, local_gis);
 
  566       for (
const std::string &transname : local_gis.transformations)
 
  567         local_workspace.interpolate_transformation(transname)
 
  568           ->init(local_workspace);
 
  570       if (!extract_variable_done) {
 
  571         std::set<var_trans_pair> vars;
 
  572         extract_variables(workspace, vars, 
true, source_mesh, 
"");
 
  575       for (
const var_trans_pair &var : used_vars) {
 
  576         workspace_gis_pair &pwi = compiled_derivatives[var];
 
  577         pwi.workspace() = local_workspace;
 
  578         pwi.gis() = ga_instruction_set();
 
  579         if (pwi.workspace().nb_trees()) {
 
  580           ga_tree tree = *(pwi.workspace().tree_info(0).ptree);
 
  581           ga_derivative(tree, pwi.workspace(), source_mesh,
 
  582                         var.varname, var.transname, 1);
 
  584             ga_semantic_analysis(tree, local_workspace, dummy_mesh(),
 
  586           ga_compile_interpolation(pwi.workspace(), pwi.gis());
 
  591       if (recompute_elt_boxes) {
 
  593         box_to_convexes.clear();
 
  594         element_boxes.clear();
 
  595         base_node bmin(N), bmax(N);
 
  596         const mesh_region &mr = target_mesh.region(target_region);
 
  597         const dal::bit_vector&
 
  599                        ? target_mesh.convex_index() : mr.index();
 
  600         for (dal::bv_visitor cv(convex_index); !cv.finished(); ++cv) {
 
  606             gmm::copy(target_mesh.points_of_convex(cv)[0], bmin);
 
  612           mesh::ref_mesh_pt_ct cvpts = target_mesh.points_of_convex(cv);
 
  615             const base_node &pt = cvpts[ip];
 
  617               bmin[k] = std::min(bmin[k], pt[k]);
 
  618               bmax[k] = std::max(bmax[k], pt[k]);
 
  622           scalar_type h = bmax[0] - bmin[0];
 
  623           for (
size_type k = 1; k < N; ++k) h = std::max(h, bmax[k]-bmin[k]);
 
  624           if (pgt->is_linear()) h *= 1E-4;
 
  625           for (
auto &&val : bmin) val -= h*0.2;
 
  626           for (
auto &&val : bmax) val += h*0.2;
 
  628           box_to_convexes[element_boxes.add_box(bmin, bmax)].push_back(cv);
 
  630         element_boxes.build_tree();
 
  631         recompute_elt_boxes = 
false;
 
  635     void finalize()
 const {
 
  636       for (
const std::string &transname : local_gis.transformations)
 
  637         local_workspace.interpolate_transformation(transname)->finalize();
 
  638       local_gis = ga_instruction_set();
 
  641     std::string expression()
 const { 
return expr; }
 
  643     int transform(
const ga_workspace &, 
const mesh &m,
 
  644                   fem_interpolation_context &ctx_x,
 
  645                   const base_small_vector &Normal,
 
  650                   std::map<var_trans_pair, base_tensor> &derivatives,
 
  651                   bool compute_derivatives)
 const {
 
  654       local_gis.ctx = ctx_x;
 
  655       local_gis.Normal = Normal;
 
  659       gmm::clear(local_workspace.assembled_tensor().as_vector());
 
  661       for (
auto &&instr : local_gis.all_instructions) {
 
  662         GMM_ASSERT1(instr.second.m == &m,
 
  663                     "Incompatibility of meshes in interpolation");
 
  664         auto &gilb = instr.second.begin_instructions;
 
  665         for (
size_type j = 0; j < gilb.size(); ++j) j += gilb[j]->exec();
 
  666         auto &gile = instr.second.elt_instructions;
 
  667         for (
size_type j = 0; j < gile.size(); ++j) j+=gile[j]->exec();
 
  668         auto &gil = instr.second.instructions;
 
  669         for (
size_type j = 0; j < gil.size(); ++j) j += gil[j]->exec();
 
  672       GMM_ASSERT1(local_workspace.assembled_tensor().size()==target_mesh.dim(),
 
  673                   "Wrong dimension of the transformation expression");
 
  674       P.resize(target_mesh.dim());
 
  675       gmm::copy(local_workspace.assembled_tensor().as_vector(), P);
 
  679       bgeot::rtree::pbox_cont boxes;
 
  681         bgeot::rtree::pbox_set bset;
 
  682         element_boxes.find_boxes_at_point(P, bset);
 
  685         std::set<std::pair<scalar_type, const bgeot::box_index*>,
 
  686                  rated_box_index_compare> rated_boxes;
 
  687         for (
const auto &box : bset) {
 
  688           scalar_type rating = scalar_type(1);
 
  689           for (
size_type i = 0; i < m.dim(); ++i) {
 
  690             scalar_type h = box->max->at(i) - box->min->at(i);
 
  691             if (h > scalar_type(0)) {
 
  692               scalar_type r = std::min(box->max->at(i) - P[i],
 
  693                                        P[i] - box->min->at(i)) / h;
 
  694               rating = std::min(r, rating);
 
  697           rated_boxes.insert(std::make_pair(rating, box));
 
  701         for (
const auto &p : rated_boxes)
 
  702           boxes.push_back(p.second);
 
  706       scalar_type best_dist(1e10);
 
  708       base_node best_P_ref;
 
  709       for (
size_type i = boxes.size(); i > 0 && !ret_type; --i) {
 
  710         for (
auto convex : box_to_convexes.at(boxes[i-1]->id)) {
 
  711           gic.init(target_mesh.points_of_convex(convex),
 
  712                    target_mesh.trans_of_convex(convex));
 
  715           bool is_in = gic.
invert(P, P_ref, converged, 1E-4);
 
  730                 = target_mesh.trans_of_convex(cv)->convex_ref()->is_in(P_ref);
 
  731               if (dist < best_dist) {
 
  741       if (ret_type == 0 && best_dist < 5e-3) {
 
  753       if (compute_derivatives) { 
 
  754         for (
auto &&d : derivatives) {
 
  755           workspace_gis_pair &pwi = compiled_derivatives[d.first];
 
  757           gmm::clear(pwi.workspace().assembled_tensor().as_vector());
 
  758           ga_function_exec(pwi.gis());
 
  759           d.second = pwi.workspace().assembled_tensor();
 
  765     interpolate_transformation_expression
 
  766     (
const mesh &sm, 
const mesh &tm, 
size_type trg, 
const std::string &expr_)
 
  767       : source_mesh(sm), target_mesh(tm), target_region(trg), expr(expr_),
 
  768         recompute_elt_boxes(true), extract_variable_done(false),
 
  769         extract_data_done(false)
 
  770     { this->add_dependency(tm); }
 
  776   (ga_workspace &workspace, 
const std::string &name, 
const mesh &sm,
 
  777    const mesh &tm, 
const std::string &expr) {
 
  779     (workspace, name, sm, tm, 
size_type(-1), expr);
 
  783   (ga_workspace &workspace, 
const std::string &name, 
const mesh &sm,
 
  784    const mesh &tm, 
size_type trg, 
const std::string &expr) {
 
  785     pinterpolate_transformation
 
  786       p = std::make_shared<interpolate_transformation_expression>
 
  788     workspace.add_interpolate_transformation(name, p);
 
  792   (model &md, 
const std::string &name, 
const mesh &sm, 
const mesh &tm,
 
  793    const std::string &expr) {
 
  799   (model &md, 
const std::string &name, 
const mesh &sm, 
const mesh &tm,
 
  800    size_type trg, 
const std::string &expr) {
 
  801     pinterpolate_transformation
 
  802       p = std::make_shared<interpolate_transformation_expression>
 
  804     md.add_interpolate_transformation(name, p);
 
  811   class interpolate_transformation_neighbor
 
  812     : 
public virtual_interpolate_transformation, 
public context_dependencies {
 
  815     void update_from_context()
 const {}
 
  816     void extract_variables(
const ga_workspace &,
 
  817                            std::set<var_trans_pair> &,
 
  819                            const std::string &)
 const {}
 
  820     void init(
const ga_workspace &)
 const {}
 
  821     void finalize()
 const {}
 
  823     std::string expression(
void)
 const { 
return "X"; }
 
  825     int transform(
const ga_workspace &, 
const mesh &m_x,
 
  826                   fem_interpolation_context &ctx_x,
 
  827                   const base_small_vector &, 
const mesh **m_t,
 
  831                   std::map<var_trans_pair, base_tensor> &,
 
  832                   bool compute_derivatives)
 const {
 
  838       GMM_ASSERT1(face_x != 
short_type(-1), 
"Neighbor transformation can " 
  839                   "only be applied to internal faces");
 
  841       auto adj_face = m_x.adjacent_face(cv_x, face_x);
 
  845         gic.init(m_x.points_of_convex(adj_face.cv),
 
  846                  m_x.trans_of_convex(adj_face.cv));
 
  847         bool converged = 
true;
 
  848         gic.
invert(ctx_x.xreal(), P_ref, converged);
 
  849         bool is_in = (ctx_x.pgt()->convex_ref()->is_in(P_ref) < 1E-4);
 
  850         GMM_ASSERT1(is_in && converged, 
"Geometric transformation inversion " 
  851                     "has failed in neighbor transformation");
 
  852         face_num = adj_face.f;
 
  856       GMM_ASSERT1(!compute_derivatives,
 
  857                   "No derivative for this transformation");
 
  861     interpolate_transformation_neighbor() { }
 
  867     return (std::make_shared<interpolate_transformation_neighbor>());
 
  874   class interpolate_transformation_element_extrapolation
 
  875     : 
public virtual_interpolate_transformation, 
public context_dependencies {
 
  878     std::map<size_type, size_type> elt_corr;
 
  881     void update_from_context()
 const {}
 
  882     void extract_variables(
const ga_workspace &,
 
  883                            std::set<var_trans_pair> &,
 
  885                            const std::string &)
 const {}
 
  886     void init(
const ga_workspace &)
 const {}
 
  887     void finalize()
 const {}
 
  888     std::string expression(
void)
 const { 
return "X"; }
 
  890     int transform(
const ga_workspace &, 
const mesh &m_x,
 
  891                   fem_interpolation_context &ctx_x,
 
  892                   const base_small_vector &, 
const mesh **m_t,
 
  896                   std::map<var_trans_pair, base_tensor> &,
 
  897                   bool compute_derivatives)
 const {
 
  900       GMM_ASSERT1(&sm == &m_x, 
"Bad mesh");
 
  901       size_type cv_x = ctx_x.convex_num(), cv_y = cv_x;
 
  902       auto it = elt_corr.find(cv_x);
 
  903       if (it != elt_corr.end()) cv_y = it->second;
 
  907         gic.init(m_x.points_of_convex(cv_y),
 
  908                  m_x.trans_of_convex(cv_y));
 
  909         bool converged = 
true;
 
  910         gic.
invert(ctx_x.xreal(), P_ref, converged, 1E-4);
 
  911         GMM_ASSERT1(converged, 
"Geometric transformation inversion " 
  912                     "has failed in element extrapolation transformation");
 
  919         P_ref = ctx_x.xref();
 
  922       GMM_ASSERT1(!compute_derivatives,
 
  923                   "No derivative for this transformation");
 
  927     void set_correspondence(
const std::map<size_type, size_type> &ec) {
 
  931     interpolate_transformation_element_extrapolation
 
  932     (
const mesh &sm_, 
const std::map<size_type, size_type> &ec)
 
  933       : sm(sm_), elt_corr(ec) { }
 
  937   void add_element_extrapolation_transformation
 
  938   (model &md, 
const std::string &name, 
const mesh &sm,
 
  939    std::map<size_type, size_type> &elt_corr) {
 
  940     pinterpolate_transformation
 
  941       p = std::make_shared<interpolate_transformation_element_extrapolation>
 
  943     md.add_interpolate_transformation(name, p);
 
  946   void add_element_extrapolation_transformation
 
  947   (ga_workspace &workspace, 
const std::string &name, 
const mesh &sm,
 
  948    std::map<size_type, size_type> &elt_corr) {
 
  949     pinterpolate_transformation
 
  950       p = std::make_shared<interpolate_transformation_element_extrapolation>
 
  952     workspace.add_interpolate_transformation(name, p);
 
  955   void set_element_extrapolation_correspondence
 
  956   (ga_workspace &workspace, 
const std::string &name,
 
  957    std::map<size_type, size_type> &elt_corr) {
 
  958     GMM_ASSERT1(workspace.interpolate_transformation_exists(name),
 
  959                 "Unknown transformation");
 
  960     auto pit=workspace.interpolate_transformation(name).get();
 
  962       = 
dynamic_cast<const interpolate_transformation_element_extrapolation *
> 
  965                 "The transformation is not of element extrapolation type");
 
  966     const_cast<interpolate_transformation_element_extrapolation *
>(cpext)
 
  967       ->set_correspondence(elt_corr);
 
  970   void set_element_extrapolation_correspondence
 
  971   (model &md, 
const std::string &name,
 
  972    std::map<size_type, size_type> &elt_corr) {
 
  973     GMM_ASSERT1(md.interpolate_transformation_exists(name),
 
  974                 "Unknown transformation");
 
  975     auto pit=md.interpolate_transformation(name).get();
 
  977       = 
dynamic_cast<const interpolate_transformation_element_extrapolation *
> 
  980                 "The transformation is not of element extrapolation type");
 
  981     const_cast<interpolate_transformation_element_extrapolation *
>(cpext)
 
  982       ->set_correspondence(elt_corr);
 
  991   class standard_secondary_domain : 
public virtual_secondary_domain {
 
  995     virtual const mesh_region &give_region(
const mesh &,
 
 1001     standard_secondary_domain(
const mesh_im &mim__, 
const mesh_region ®ion_)
 
 1002       : virtual_secondary_domain(mim__, region_) {}
 
 1005   void add_standard_secondary_domain
 
 1006   (model &md, 
const std::string &name, 
const mesh_im &mim,
 
 1007    const mesh_region &rg) { 
 
 1008     psecondary_domain p = std::make_shared<standard_secondary_domain>(mim, rg);
 
 1009     md.add_secondary_domain(name, p);
 
 1012   void add_standard_secondary_domain
 
 1013   (ga_workspace &workspace, 
const std::string &name, 
const mesh_im &mim,
 
 1014    const mesh_region &rg) { 
 
 1015     psecondary_domain p = std::make_shared<standard_secondary_domain>(mim, rg);
 
 1016     workspace.add_secondary_domain(name, p);
 
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 ...
 
Balanced tree of n-dimensional rectangles.
 
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.
 
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.
 
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.
 
Describe an integration method linked to a mesh.
 
"iterator" class for regions.
 
structure used to hold a set of convexes and/or convex faces.
 
static mesh_region all_convexes()
provide a default value for the mesh_region parameters of assembly procedures etc.
 
Describe a mesh (collection of convexes (elements) and points).
 
`‘Model’' variables store the variables, the data and the description of a model.
 
Semantic analysis of assembly trees and semantic manipulations.
 
Compilation and execution operations.
 
void copy(const L1 &l1, L2 &l2)
*/
 
void clear(L &l)
clear (fill with zeros) a vector or matrix.
 
void resize(V &v, size_type n)
*/
 
void add(const L1 &l1, L2 &l2)
*/
 
void asm_mass_matrix(const MAT &M, const mesh_im &mim, const mesh_fem &mf1, const mesh_region &rg=mesh_region::all_convexes())
generic mass matrix assembly (on the whole mesh or on the specified convex set or boundary)
 
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
 
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.
 
pinterpolate_transformation interpolate_transformation_neighbor_instance()
Create a new instance of a transformation corresponding to the interpolation on the neighbor element.
 
void add_interpolate_transformation_from_expression(ga_workspace &workspace, const std::string &transname, const mesh &source_mesh, const mesh &target_mesh, const std::string &expr)
Add a transformation to a workspace workspace or a model md mapping point in mesh source_mesh to mesh...
 
void ga_local_projection(const getfem::model &md, const mesh_im &mim, const std::string &expr, const mesh_fem &mf, base_vector &result, const mesh_region &rg=mesh_region::all_convexes())
Make an elementwise L2 projection of an expression with respect to the mesh_fem mf.