31 level_set_contact::contact_body::contact_body(model& _md, std::string _var_name):
34 own_mesh(const_cast<mesh&>(_md.mesh_fem_of_variable(_var_name).
36 own_mesh_fem(_md.mesh_fem_of_variable(_var_name)),
45 ls_name(
"ls_on_"+_var_name),
46 ls_mesh_fem(_md.mesh_fem_of_variable(_var_name)),
51 model_real_plain_vector LS(ls_mesh_fem.
nb_dof());
59 getfem::model& _md, std::string _var_name, std::string _ls_name):
67 for(
size_type i=0;i<ls_values().size();i++)
73 const std::string& _var_name,
78 mult_mim_order(_mult_mim_order),
80 mult_mf_order(_mult_order),
81 integration(PER_ELEMENT),
82 regularized_tollerance(0),
83 small_weight_multiplier(0),
89 get_mesh().
region(VOLUME_ELEMENTS).add(get_mesh().convex_index());
94 get_mesh().
region(BOUNDARY_ELEMENTS).clear();
96 masters.push_back(
this);
101 const std::string& _var_name,
103 const std::string& _mult_mim_method,
104 contact_integration _integration,
105 scalar_type _regularized_tollerance,
106 scalar_type _small_weight_multiplier,
107 scalar_type _max_contact_angle):
111 mult_int_method(_mult_mim_method),
112 mult_mf_order(_mult_order),
113 integration(_integration),
114 regularized_tollerance(_regularized_tollerance),
115 small_weight_multiplier(_small_weight_multiplier),
116 max_contact_angle(_max_contact_angle)
121 get_mesh().
region(VOLUME_ELEMENTS).add(get_mesh().convex_index());
126 get_mesh().
region(BOUNDARY_ELEMENTS).clear();
127 masters.push_back(
this);
133 const std::string& slave_var_name)
const
135 auto it = contact_table.find(slave_var_name);
136 if (it!=contact_table.end())
return *(it->second);
137 GMM_ASSERT1(
false,
"did not find info on slave contact body, \
138 defined on variable "+slave_var_name);
143 const std::string& slave_var_name)
145 auto it = contact_table.find(slave_var_name);
146 if (it!=contact_table.end())
return *(it->second);
147 GMM_ASSERT1(
false,
"did not find info on slave contact body, \
148 defined on variable "+slave_var_name);
155 auto it = border_faces.find(i);
156 if (it!=border_faces.end())
return it->second;
157 GMM_ASSERT1(
false,
"did not find a face, corresponding to element "<<i);
165 GMM_ASSERT1(&md==&scb.get_model(),
166 "Model objects of master and slave are not the same");
167 if (assumed_contact_region!=
size_type(-1))
168 GMM_ASSERT1(get_mesh().region(assumed_contact_region).is_boundary(),
169 "Assumed_contact_region must be on the boundary");
175 std::shared_ptr<getfem::mr_visitor> i;
180 if (assumed_contact_region==
size_type(-1)){
181 i = std::make_shared<getfem::mr_visitor>(outer_faces);
186 region(assumed_contact_region);
187 i = std::make_shared<getfem::mr_visitor>(assumed_region);
190 for (; !i->finished(); ++(*i)){
192 get_mesh().add_convex(
194 get_mesh().trans_of_convex(i->cv())),
195 get_mesh().ind_points_of_face_of_convex(
196 i->cv(), i->f()).begin());
199 border_faces[new_elem] = face_type(*i);
200 contact_elems.add(new_elem);
201 boundary_elems.add(new_elem);
204 GMM_ASSERT1(get_mesh().region(BOUNDARY_ELEMENTS).index().card()!=0,
205 "No boundary elements added !!!");
207 GMM_ASSERT1(get_mesh().region(assumed_contact_elems).index().card()!=0,
208 "No contact elements added !!!");
211 std::string mult_name = md.new_name(
"mult_on_"+get_var_name()+
212 "_and_"+scb.get_var_name());
215 bgeot::dim_type(mult_mf_order), bgeot::dim_type(1));
216 md.add_multiplier(mult_name,mf_mult,get_var_name());
221 plain_vector LS(mf_ls.
nb_dof());
222 md.add_initialized_fem_data(
"ls_on"+get_var_name()+
223 "_from_"+scb.get_var_name(),mf_ls,LS);
226 contact_table[scb.get_var_name()] =
227 std::make_shared<contact_pair_info>(*
this,scb,mult_name,assumed_contact_elems);
231 std::vector<level_set_contact::master_contact_body*>
232 level_set_contact::master_contact_body::masters;
237 if (masters.size()==0) GMM_WARNING3(
"Running contact detection, while no \
238 contact bodies are registered");
239 bool contact_surfaces_changed =
false;
241 if (masters[i]->master_contact_changed())
242 contact_surfaces_changed=
true;
244 return contact_surfaces_changed;
249 if (masters.size()==0) GMM_WARNING3(
"Clearing contact lists, while no \
250 contact bodies are registered");
252 masters[i]->clear_contact_history();
257 std::map<std::string, std::shared_ptr<contact_pair_info> >::
258 iterator it = contact_table.begin();
259 for(;it!=contact_table.end();it++)
260 it->second->clear_contact_history();
265 bool contact_surfaces_changed =
false;
266 std::map<std::string, std::shared_ptr<contact_pair_info> >::
267 iterator it = contact_table.begin();
268 for(;it!=contact_table.end();it++)
269 if (it->second->contact_changed())
270 contact_surfaces_changed=
true;
272 return contact_surfaces_changed;
279 std::shared_ptr<getfem::mesh_im> pmim_contact;
281 pmim_contact = std::make_shared<mesh_im>(get_mesh());
283 pmim_contact->set_integration_method
284 (get_mesh().region(region_id).index(),
285 bgeot::dim_type(contact_mim_order()));
289 pmim_contact->set_integration_method
290 (get_mesh().region(region_id).index(), contact_int_method());
297 level_set_contact::contact_pair_update::contact_pair_update(
305 GMM_ASSERT1(!mcb.is_mesh_deformed(),
"Trying to deform \
306 already deformed Master Contact Body");
307 GMM_ASSERT1(!scb.is_mesh_deformed(),
"Trying to deform \
308 already deformed Slave Contact Body");
310 const model_real_plain_vector&
311 Umaster=mcb.get_model().real_variable(mcb.get_var_name());
314 def_master = std::make_shared<getfem::temporary_mesh_deformator<>>
315 (mcb.get_mesh_fem(),Umaster);
316 mcb.is_deformed=
true;
317 if (&mcb.get_mesh()!=&scb.get_mesh()){
319 const model_real_plain_vector&
320 Uslave=scb.get_model().real_variable(scb.get_var_name());
321 def_slave = std::make_shared<getfem::temporary_mesh_deformator<>>
322 (scb.get_mesh_fem(),Uslave);
323 scb.is_deformed=
true;
325 if (ud == FULL_UPDATE) mcb.update_for_slave(scb.get_var_name());
328 level_set_contact::contact_pair_update::~contact_pair_update(){
329 mcb.is_deformed=
false;
330 scb.is_deformed=
false;
335 level_set_contact::contact_pair_info::contact_pair_info(
336 master_contact_body& underformed_mcb,
337 slave_contact_body& underformed_scb,
338 const std::string& _mult_name,
341 master_cb(underformed_mcb),
342 slave_cb(underformed_scb),
343 mult_name(_mult_name),
344 GIVEN_CONTACT_REGION(_GIVEN_CONTACT_REGION),
346 ACTIVE_CONTACT_REGION(
getfem::mesh_region::free_region_id(master_cb.get_mesh())),
347 members_are_computed(false),
348 init_cont_detect_done(false)
354 GMM_ASSERT1(master_cb.get_mesh().
355 region(GIVEN_CONTACT_REGION).index().card()!=0,
356 "provided contact region for contact_pair_info class is empty!!!");
361 old_contact_elm_list.clear();
362 pre_old_ct_list.clear();
369 temp_mesh_deformation(master_cb,slave_cb,DEFORM_MESHES_ONLY);
372 mesh_fem mf_scalar(master_cb.get_mesh());
381 model_real_plain_vector LS_on_contour(mf_boundary.
nb_dof());
383 slave_cb.ls_values(), LS_on_contour);
384 model_real_plain_vector LS(mf_scalar.
nb_dof());
385 mf_boundary.extend_vector(LS_on_contour,LS);
386 gmm::copy(LS,master_cb.get_model().set_real_variable
387 (
"ls_on"+master_cb.get_var_name()+
"_from_"+slave_cb.get_var_name()));
391 mesh_fem mf_gradient_ls(slave_cb.get_mesh());
393 mesh_fem mf_gradient_ls_vect(mf_gradient_ls);
394 mf_gradient_ls_vect.
set_qdim(slave_cb.get_mesh().dim());
395 plain_vector GradLS(mf_gradient_ls.
nb_dof()*slave_cb.get_mesh().dim());
398 mf_boundary_vect.
adapt(master_cb.get_mesh_fem().dof_on_region(GIVEN_CONTACT_REGION));
399 plain_vector GradLS_boundary(mf_boundary.
nb_dof()*slave_cb.get_mesh().dim());
402 size_type dim = slave_cb.get_mesh().dim();
403 const scalar_type TINY = 1e-15;
406 for(
size_type j=0;j<dim;j++) ls_node[j]=GradLS_boundary[dim*i+j];
407 ls_node/= (gmm::vect_norm2(ls_node)+TINY);
408 for(
size_type j=0;j<dim;j++) GradLS_boundary[dim*i+j]=ls_node[j];
410 plain_vector normLS_master(master_cb.get_mesh_fem().nb_dof());
411 mf_boundary_vect.extend_vector(GradLS_boundary,normLS_master);
416 master_cb.get_model().mesh_fem_of_variable(mult_name);
417 const model_real_plain_vector& lambda =
418 master_cb.get_model().real_variable(mult_name);
419 model_real_plain_vector lambda_full(mf_mult.
nb_basic_dof());
420 if (lambda.size()>0) mf_mult.extend_vector(lambda,lambda_full);
422 dal::bit_vector cc = master_cb.get_mesh().
423 region(GIVEN_CONTACT_REGION).index();
424 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).clear();
425 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).add(cc);
432 face_type face = master_cb.ext_face_of_elem(o);
434 master_cb.get_mesh().normal_of_face_of_convex(face.cv,face.f);
435 unit_face_normal/=gmm::vect_norm2(unit_face_normal);
436 scalar_type cosine_alpha = 0;
437 for (
size_type j = 0; j < dof_ls.size(); j++){
440 ls_grad_node[k]=normLS_master[dim*dof_ls[j]+k];
441 cosine_alpha += gmm::vect_sp(ls_grad_node,unit_face_normal);
443 cosine_alpha /= scalar_type(dof_ls.size());
444 scalar_type alpha = acos(cosine_alpha)*360/(2*M_PI);
447 scalar_type LS_extreeme = LS[dof_ls[0]];
448 if (master_cb.integration==master_contact_body::PER_ELEMENT)
449 for (
size_type j = 0; j < dof_ls.size(); j++)
450 LS_extreeme=std::min(LS[dof_ls[j]],LS_extreeme);
452 for (
size_type j = 0; j < dof_ls.size(); j++)
453 LS_extreeme=std::max(LS[dof_ls[j]],LS_extreeme);
455 scalar_type LM_sum = 0;
456 for (
size_type j = 0; j < dof_lm.size(); j++)
457 LM_sum+=lambda_full[dof_lm[j]];
459 const scalar_type TINY_2 = 1e-9;
461 if (LS_extreeme+LM_sum < TINY_2 || alpha > master_cb.max_contact_angle)
462 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).sup(o);
466 bool contact_surface_changed;
467 const dal::bit_vector& current_contact_elm_list =
468 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).index();
469 GMM_TRACE2(
"Current contact elements: "<< current_contact_elm_list);
470 GMM_TRACE2(
"Old contact elements: "<< old_contact_elm_list);
471 GMM_TRACE2(
"Pre-old contact elements: "<< pre_old_ct_list);
473 if (current_contact_elm_list == old_contact_elm_list &&
474 current_contact_elm_list.card() == old_contact_elm_list.card()) {
475 contact_surface_changed =
false;
476 GMM_TRACE2(
" the contact area has not changed");
478 if (current_contact_elm_list == pre_old_ct_list &&
479 current_contact_elm_list.card() == pre_old_ct_list.card()) {
480 contact_surface_changed =
false;
481 GMM_TRACE2(
" the contact area has changed, but cycling, \
482 so exiting active set search");
484 contact_surface_changed =
true;
485 GMM_TRACE2(
" the contact area has changed");
486 pre_old_ct_list = old_contact_elm_list;
487 old_contact_elm_list = current_contact_elm_list;
491 init_cont_detect_done =
true;
496 pmim_contact = master_cb.build_mesh_im_on_boundary(ACTIVE_CONTACT_REGION);
497 n_integrated_elems = pmim_contact->convex_index().card();
498 GMM_ASSERT1(n_integrated_elems==current_contact_elm_list.card(),
499 "Failure in integration method: The number of integrated elements "
500 "does not correspond to the number of contact elements");
502 return contact_surface_changed;
510 GMM_ASSERT1(master_cb.is_mesh_deformed(),
"Master mesh is not deformed, \
511 cannot calucalte contact info");
513 GMM_ASSERT1(slave_cb.is_mesh_deformed(),
"Slave mesh is not deformed, \
514 cannot calucalte contact info");
516 GMM_ASSERT1(master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).index().card()>0,
517 "Internal error: Contact area is empty");
520 pinterpolated_fem = std::make_shared<mesh_fem>(master_cb.get_mesh());
522 pinterpolated_fem_U = std::shared_ptr<mesh_fem>();
527 *pmim_contact, 0, dal::bit_vector(),
false);
528 pinterpolated_fem->set_finite_element(
529 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).index(),ifem_srf);
530 pinterpolated_fem->set_qdim(1);
534 pinterpolated_fem_U = std::make_shared<mesh_fem>(master_cb.get_mesh());
535 pinterpolated_fem_U->set_finite_element(master_cb.get_mesh().
536 region(ACTIVE_CONTACT_REGION).index(),ifem_srf);
537 pinterpolated_fem_U->set_qdim(master_cb.get_mesh().dim());
540 std::vector<size_type> index(pinterpolated_fem->nb_dof());
542 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).index();
543 for (dal::bv_visitor icv(cc); !icv.finished(); ++icv){
544 for (
size_type j = 0; j < pinterpolated_fem->nb_basic_dof_of_element(icv);
546 {index[pinterpolated_fem->ind_basic_dof_of_element(icv)[j]]
547 = ifem_srf->index_of_global_dof(icv, j);}
550 slave_ls_dofs = std::make_shared<gmm::unsorted_sub_index>(index);
553 std::vector<size_type> indexU(pinterpolated_fem_U->nb_dof());
554 size_type dim = pinterpolated_fem_U->get_qdim();
556 for(
size_type i=0;i<pinterpolated_fem->nb_dof();i++)
557 indexU[dim*i+d] = dim*index[i]+d;
558 slave_U_dofs = std::make_shared<gmm::unsorted_sub_index>(indexU);
560 members_are_computed=
true;
571 getfem::pbrick pbr = std::make_shared<level_set_contact_brick>(md,mcb,scb,rg);
574 const std::string& name_Um = mcb.get_var_name();
575 const std::string& name_Us = scb.get_var_name();
576 const std::string& name_LM = mcb.
get_pair_info(name_Us).get_mult_name();
577 model::termlist terms;
578 terms.push_back(model::term_description(name_Um,name_Um,
false));
579 terms.push_back(model::term_description(name_Us,name_Us,
false));
580 terms.push_back(model::term_description(name_LM,name_LM,
false));
581 terms.push_back(model::term_description(name_Um,name_Us,
true));
582 terms.push_back(model::term_description(name_Um,name_LM,
true));
583 terms.push_back(model::term_description(name_Us,name_LM,
true));
586 model::varnamelist variables;
587 variables.push_back(name_Um);
588 variables.push_back(name_Us);
589 variables.push_back(name_LM);
594 model::varnamelist datalist;
595 model::mimlist mimlist;
598 return md.
add_brick(pbr,variables,datalist,terms,mimlist,rg);
602 level_set_contact::level_set_contact_brick::
603 level_set_contact_brick(
605 master_contact_body& _mcb,
606 slave_contact_body& _scb,
608 md(_md),mcb(_mcb),scb(_scb), given_contact_id(rg)
610 GMM_ASSERT1(&md == &mcb.get_model(),
611 "Master body is defined on a different model then the input");
614 mcb.add_slave(scb,given_contact_id);
617 contact_region_id = mcb.get_pair_info(scb.get_var_name()).contact_region();
619 mcb.get_mesh().intersect_with_mpi_region(contact_region_);
620 contact_region_id = contact_region_.id();
623 set_flags(
"Level set contact brick",
634 const model::varnamelist &vl,
635 const model::varnamelist &,
636 const model::mimlist &,
637 model::real_matlist &matl,
638 model::real_veclist &vecl,
639 model::real_veclist &,
641 build_version version)
const {
643 GMM_ASSERT1(vl.size() == 3,
644 "Level set contact brick needs three variables");
645 GMM_ASSERT1(matl.size() == 6,
646 "Level set contact brick needs six matrices");
647 GMM_ASSERT1(vecl.size() == 6,
648 "Level set contact brick assembles size RHSs");
649 GMM_ASSERT1(region==given_contact_id,
650 "Assumed contact region has changed!!! \
651 This implementation does not handle this \
652 for efficiency reasons!!");
654 if (version & model::BUILD_MATRIX )
655 for(
size_type i=0;i<matl.size();i++) gmm::clear(matl[i]);
656 if (version & model::BUILD_RHS )
657 for(
size_type i=0;i<vecl.size();i++) gmm::clear(vecl[i]);
660 mcb.get_mesh().
region(contact_region_id);
661 if (active_contact_region.
index().card()==0)
return;
670 if (version & model::BUILD_MATRIX ) {
671 GMM_TRACE2(
"Level set contact brick stiffness matrix assembly on "
672 << mcb.
get_pair_info(scb.get_var_name()).num_of_integr_elems()
674 asm_level_set_contact_tangent_matrix(matl,mcb,scb,LM,active_contact_region);
678 if (version & model::BUILD_RHS ) {
679 GMM_TRACE2(
"Level set contact brick RHS assembly on "
680 << mcb.
get_pair_info(scb.get_var_name()).num_of_integr_elems()
682 asm_level_set_contact_rhs(vecl,mcb,scb,LM,active_contact_region);
684 gmm::scale(vecl[i], scalar_type(-1));
689 void level_set_contact::NormalTerm::compute(
691 bgeot::base_tensor &t)
694 size_type cv_volume = mcb.ext_face_of_elem(cv).cv;
698 un /= gmm::vect_norm2(un);
701 for (
size_type i = 0; i < dim; i++) t[i] = un[i];
705 if (i == j) t(i, j) = 1.0 - un[i] * un[j];
706 else t(i, j) =-un[i] * un[j];
711 level_set_contact::HFunction::HFunction(
712 const mesh_fem &lsmf_,
713 const plain_vector &LS_U_,
715 scalar_type small_h_):
724 const bgeot::multi_index& level_set_contact::HFunction::
727 void level_set_contact::HFunction::
731 bgeot::base_tensor &t)
738 plain_vector ls_interpolated(1);
739 ctx.
pf()->interpolation(ctx,U,ls_interpolated,1);
740 t[0] = hRegularized(ls_interpolated[0],m_Epsilon,small_h);
743 bgeot::scalar_type level_set_contact::HFunction::
744 hRegularized(scalar_type f, scalar_type epsilon, scalar_type small_h_)
746 if (f>epsilon)
return 1.0;
747 if (f<(-epsilon))
return small_h_;
748 return 0.5+0.125*(9.0*f/(epsilon)-5.0*pow(f/(epsilon),scalar_type(3)));
752 level_set_contact::Unity::Unity(
const mesh_fem &mf_):mf(mf_),sizes_(1)
754 const bgeot::multi_index& level_set_contact::Unity::sizes(
size_type)
const {
return sizes_;}
755 void level_set_contact::Unity::
757 void level_set_contact::Unity::
761 void level_set_contact::
767 const std::string& lsolver_name,
768 getfem::abstract_newton_line_search &ls)
770 bool active_set_converged =
false;
771 it_staggered.set_iteration(0);
776 it_newton.set_iteration(0);
777 getfem::rmodel_plsolver_type plsolver=getfem::select_linear_solver<sparse_matrix,plain_vector>(md,lsolver_name);
778 (*sf)(md,it_newton,plsolver,ls);
779 GMM_TRACE2(
"Newton converged? - "<<it_newton.converged());
780 GMM_TRACE2(
"active set converged? - "<<active_set_converged);
781 GMM_ASSERT1(it_newton.converged(),
"Newton method did not converge");
784 }
while(!active_set_converged &&
785 !it_staggered.finished(it_staggered.get_resmax()+1.0));
787 if (active_set_converged && it_newton.converged()) it_staggered.enforce_converged();
795 std::stringstream fname;
796 fname<<name.substr(0,5);
797 GMM_ASSERT1((fname.str()==
"GT_QK" || fname.str()==
"GT_PK"),
798 "Cannot handle other transformations but QK or PK,\
799 Sorry, to be implemented" );
800 std::stringstream str1(name.substr(6,1));
804 std::istringstream str2(name.substr(8,1));
808 fname<<
"("<<dim-1<<
","<<order<<
")";
const base_node & xref() const
coordinates of the current point, in the reference convex.
structure passed as the argument of fem interpolation functions.
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.
void set_classical_discontinuous_finite_element(size_type cv, dim_type fem_degree, scalar_type alpha=0, bool complete=false)
Similar to set_classical_finite_element, but uses discontinuous lagrange elements.
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.
void set_finite_element(size_type cv, pfem pf)
Set the finite element method of a convex.
virtual size_type nb_basic_dof() const
Return the total number of basic degrees of freedom (before the optional reduction).
virtual void set_qdim(dim_type q)
Change the Q dimension.
dal::bit_vector dof_on_region(const mesh_region &b) const
Get a list of dof lying on a given mesh_region.
Describe an integration method linked to a mesh.
structure used to hold a set of convexes and/or convex faces.
const dal::bit_vector & index() const
Index of the region convexes, or the convexes from the partition on the current thread.
static size_type free_region_id(const getfem::mesh &m)
Extract the next region number that does not yet exists in the mesh.
const mesh_region region(size_type id) const
Return the region of index 'id'.
`‘Model’' variables store the variables, the data and the description of a model.
size_type add_brick(pbrick pbr, const varnamelist &varnames, const varnamelist &datanames, const termlist &terms, const mimlist &mims, size_type region)
Add a brick to the model.
void add_initialized_fem_data(const std::string &name, const mesh_fem &mf, const VECT &v)
Add an initialized fixed size data to the model, assumed to be a vector field if the size of the vect...
const model_real_plain_vector & real_variable(const std::string &name, size_type niter) const
Gives the access to the vector value of a variable.
a subclass of mesh_fem which allows to eliminate a number of dof of the original mesh_fem.
void adapt(const dal::bit_vector &kept_dof, const dal::bit_vector &rejected_elt=dal::bit_vector())
build the mesh_fem keeping only the dof of the original mesh_fem which are listed in kept_dof.
size_type nb_dof(void) const
Return the total number of degrees of freedom.
The Iteration object calculates whether the solution has reached the desired accuracy,...
base class for the master and the slave contact bodies.
Master contact body which surface will be used to project contact stresses and stiffness terms.
const contact_pair_info & get_pair_info(const std::string &slave_var_name) const
access to a structure that contains all the info about contact pair between this master and a slave,...
master_contact_body(model &_md, const std::string &_var_name, size_type _mult_order, size_type _mult_mim_order)
create master contact body with a model, name where masters displacements are defined,...
bool master_contact_changed(void)
contact detection for all slaves
static bool any_contact_change()
contact detection for all masters/slave couples
std::shared_ptr< mesh_im > build_mesh_im_on_boundary(size_type region)
return a pointer to mesh_im used for contact surface calculations
void clear_contact_history(void)
clearing previous contact elem lists
void add_slave(slave_contact_body &scb, size_type slave_contact_region=-1)
associate a slave contact body with this master.
face_type ext_face_of_elem(size_type cv) const
gives a face, corresponding to newly created boundary element
static void clear_all_contact_history()
should be used in the beginning of a step to clean data structures that store previous contact elemen...
Contact body that will be projected on the boundary of the master.
void offset_level_set(scalar_type off)
adds a fixed value "off" to the level set field
slave_contact_body(model &_md, const std::string &_var_name, mesh_im *_pmim)
default constructor.
Compute the gradient of a field on a getfem::mesh_fem.
FEM which interpolates a mesh_fem on a different mesh.
a subclass of mesh_im which is conformal to a number of level sets.
Keep informations about a mesh crossed by level-sets.
void APIDECL outer_faces_of_mesh(const mesh &m, const dal::bit_vector &cvlst, convex_face_ct &flist)
returns a list of "exterior" faces of a mesh (i.e.
size_type convex_num() const
get the current convex number
const pfem pf() const
get the current FEM descriptor
gmm::uint16_type short_type
used as the common short type integer in the library
std::string name_of_geometric_trans(pgeometric_trans p)
Get the string name of a geometric transformation.
pgeometric_trans geometric_trans_descriptor(std::string name)
Get the geometric transformation from its string name.
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 compute_gradient(const mesh_fem &mf, const mesh_fem &mf_target, const VECT1 &UU, VECT2 &VV)
Compute the gradient of a field on a getfem::mesh_fem.
void del_interpolated_fem(const pfem &pf)
release an interpolated fem
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.
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.
std::shared_ptr< const virtual_brick > pbrick
type of pointer on a brick
const mesh_fem & classical_mesh_fem(const mesh &mesh, dim_type degree, dim_type qdim=1, bool complete=false)
Gives the descriptor of a classical finite element method of degree K on mesh.