30 level_set_contact::contact_body::contact_body(model& _md, std::string _var_name):
33 own_mesh(const_cast<mesh&>(_md.mesh_fem_of_variable(_var_name).
35 own_mesh_fem(_md.mesh_fem_of_variable(_var_name)),
44 ls_name(
"ls_on_"+_var_name),
45 ls_mesh_fem(_md.mesh_fem_of_variable(_var_name)),
50 model_real_plain_vector LS(ls_mesh_fem.
nb_dof());
58 getfem::model& _md, std::string _var_name, std::string _ls_name):
66 for(
size_type i=0;i<ls_values().size();i++)
72 const std::string& _var_name,
77 mult_mim_order(_mult_mim_order),
79 mult_mf_order(_mult_order),
80 integration(PER_ELEMENT),
81 regularized_tollerance(0),
82 small_weight_multiplier(0),
88 get_mesh().
region(VOLUME_ELEMENTS).add(get_mesh().convex_index());
93 get_mesh().
region(BOUNDARY_ELEMENTS).clear();
95 masters.push_back(
this);
100 const std::string& _var_name,
102 const std::string& _mult_mim_method,
103 contact_integration _integration,
104 scalar_type _regularized_tollerance,
105 scalar_type _small_weight_multiplier,
106 scalar_type _max_contact_angle):
110 mult_int_method(_mult_mim_method),
111 mult_mf_order(_mult_order),
112 integration(_integration),
113 regularized_tollerance(_regularized_tollerance),
114 small_weight_multiplier(_small_weight_multiplier),
115 max_contact_angle(_max_contact_angle)
120 get_mesh().
region(VOLUME_ELEMENTS).add(get_mesh().convex_index());
125 get_mesh().
region(BOUNDARY_ELEMENTS).clear();
126 masters.push_back(
this);
132 const std::string& slave_var_name)
const
134 auto it = contact_table.find(slave_var_name);
135 if (it!=contact_table.end())
return *(it->second);
136 GMM_ASSERT1(
false,
"did not find info on slave contact body, \
137 defined on variable "+slave_var_name);
142 const std::string& slave_var_name)
144 auto it = contact_table.find(slave_var_name);
145 if (it!=contact_table.end())
return *(it->second);
146 GMM_ASSERT1(
false,
"did not find info on slave contact body, \
147 defined on variable "+slave_var_name);
154 auto it = border_faces.find(i);
155 if (it!=border_faces.end())
return it->second;
156 GMM_ASSERT1(
false,
"did not find a face, corresponding to element "<<i);
164 GMM_ASSERT1(&md==&scb.get_model(),
165 "Model objects of master and slave are not the same");
166 if (assumed_contact_region!=
size_type(-1))
167 GMM_ASSERT1(get_mesh().region(assumed_contact_region).is_boundary(),
168 "Assumed_contact_region must be on the boundary");
174 std::shared_ptr<getfem::mr_visitor> i;
179 if (assumed_contact_region==
size_type(-1)){
180 i = std::make_shared<getfem::mr_visitor>(outer_faces);
185 region(assumed_contact_region);
186 i = std::make_shared<getfem::mr_visitor>(assumed_region);
189 for (; !i->finished(); ++(*i)){
191 get_mesh().add_convex(
193 get_mesh().trans_of_convex(i->cv())),
194 get_mesh().ind_points_of_face_of_convex(
195 i->cv(), i->f()).begin());
198 border_faces[new_elem] = face_type(*i);
199 contact_elems.add(new_elem);
200 boundary_elems.add(new_elem);
203 GMM_ASSERT1(get_mesh().region(BOUNDARY_ELEMENTS).index().card()!=0,
204 "No boundary elements added !!!");
206 GMM_ASSERT1(get_mesh().region(assumed_contact_elems).index().card()!=0,
207 "No contact elements added !!!");
210 std::string mult_name = md.new_name(
"mult_on_"+get_var_name()+
211 "_and_"+scb.get_var_name());
214 bgeot::dim_type(mult_mf_order), bgeot::dim_type(1));
215 md.add_multiplier(mult_name,mf_mult,get_var_name());
220 plain_vector LS(mf_ls.
nb_dof());
221 md.add_initialized_fem_data(
"ls_on"+get_var_name()+
222 "_from_"+scb.get_var_name(),mf_ls,LS);
225 contact_table[scb.get_var_name()] =
226 std::make_shared<contact_pair_info>(*
this,scb,mult_name,assumed_contact_elems);
230 std::vector<level_set_contact::master_contact_body*>
231 level_set_contact::master_contact_body::masters;
236 if (masters.size()==0) GMM_WARNING3(
"Running contact detection, while no \
237 contact bodies are registered");
238 bool contact_surfaces_changed =
false;
240 if (masters[i]->master_contact_changed())
241 contact_surfaces_changed=
true;
243 return contact_surfaces_changed;
248 if (masters.size()==0) GMM_WARNING3(
"Clearing contact lists, while no \
249 contact bodies are registered");
251 masters[i]->clear_contact_history();
256 std::map<std::string, std::shared_ptr<contact_pair_info> >::
257 iterator it = contact_table.begin();
258 for(;it!=contact_table.end();it++)
259 it->second->clear_contact_history();
264 bool contact_surfaces_changed =
false;
265 std::map<std::string, std::shared_ptr<contact_pair_info> >::
266 iterator it = contact_table.begin();
267 for(;it!=contact_table.end();it++)
268 if (it->second->contact_changed())
269 contact_surfaces_changed=
true;
271 return contact_surfaces_changed;
278 std::shared_ptr<getfem::mesh_im> pmim_contact;
280 pmim_contact = std::make_shared<mesh_im>(get_mesh());
282 pmim_contact->set_integration_method
283 (get_mesh().region(region_id).index(),
284 bgeot::dim_type(contact_mim_order()));
288 pmim_contact->set_integration_method
289 (get_mesh().region(region_id).index(), contact_int_method());
296 level_set_contact::contact_pair_update::contact_pair_update(
304 GMM_ASSERT1(!mcb.is_mesh_deformed(),
"Trying to deform \
305 already deformed Master Contact Body");
306 GMM_ASSERT1(!scb.is_mesh_deformed(),
"Trying to deform \
307 already deformed Slave Contact Body");
309 const model_real_plain_vector&
310 Umaster=mcb.get_model().real_variable(mcb.get_var_name());
313 def_master = std::make_shared<getfem::temporary_mesh_deformator<>>
314 (mcb.get_mesh_fem(),Umaster);
315 mcb.is_deformed=
true;
316 if (&mcb.get_mesh()!=&scb.get_mesh()){
318 const model_real_plain_vector&
319 Uslave=scb.get_model().real_variable(scb.get_var_name());
320 def_slave = std::make_shared<getfem::temporary_mesh_deformator<>>
321 (scb.get_mesh_fem(),Uslave);
322 scb.is_deformed=
true;
324 if (ud == FULL_UPDATE) mcb.update_for_slave(scb.get_var_name());
327 level_set_contact::contact_pair_update::~contact_pair_update(){
328 mcb.is_deformed=
false;
329 scb.is_deformed=
false;
334 level_set_contact::contact_pair_info::contact_pair_info(
335 master_contact_body& underformed_mcb,
336 slave_contact_body& underformed_scb,
337 const std::string& _mult_name,
340 master_cb(underformed_mcb),
341 slave_cb(underformed_scb),
342 mult_name(_mult_name),
343 GIVEN_CONTACT_REGION(_GIVEN_CONTACT_REGION),
345 ACTIVE_CONTACT_REGION(
getfem::mesh_region::free_region_id(master_cb.get_mesh())),
346 members_are_computed(false),
347 init_cont_detect_done(false)
353 GMM_ASSERT1(master_cb.get_mesh().
354 region(GIVEN_CONTACT_REGION).index().card()!=0,
355 "provided contact region for contact_pair_info class is empty!!!");
360 old_contact_elm_list.clear();
361 pre_old_ct_list.clear();
368 temp_mesh_deformation(master_cb,slave_cb,DEFORM_MESHES_ONLY);
371 mesh_fem mf_scalar(master_cb.get_mesh());
380 model_real_plain_vector LS_on_contour(mf_boundary.
nb_dof());
382 slave_cb.ls_values(), LS_on_contour);
383 model_real_plain_vector LS(mf_scalar.
nb_dof());
384 mf_boundary.extend_vector(LS_on_contour,LS);
385 gmm::copy(LS,master_cb.get_model().set_real_variable
386 (
"ls_on"+master_cb.get_var_name()+
"_from_"+slave_cb.get_var_name()));
390 mesh_fem mf_gradient_ls(slave_cb.get_mesh());
392 mesh_fem mf_gradient_ls_vect(mf_gradient_ls);
393 mf_gradient_ls_vect.
set_qdim(slave_cb.get_mesh().dim());
394 plain_vector GradLS(mf_gradient_ls.
nb_dof()*slave_cb.get_mesh().dim());
397 mf_boundary_vect.
adapt(master_cb.get_mesh_fem().dof_on_region(GIVEN_CONTACT_REGION));
398 plain_vector GradLS_boundary(mf_boundary.
nb_dof()*slave_cb.get_mesh().dim());
401 size_type dim = slave_cb.get_mesh().dim();
402 const scalar_type TINY = 1e-15;
405 for(
size_type j=0;j<dim;j++) ls_node[j]=GradLS_boundary[dim*i+j];
406 ls_node/= (gmm::vect_norm2(ls_node)+TINY);
407 for(
size_type j=0;j<dim;j++) GradLS_boundary[dim*i+j]=ls_node[j];
409 plain_vector normLS_master(master_cb.get_mesh_fem().nb_dof());
410 mf_boundary_vect.extend_vector(GradLS_boundary,normLS_master);
415 master_cb.get_model().mesh_fem_of_variable(mult_name);
416 const model_real_plain_vector& lambda =
417 master_cb.get_model().real_variable(mult_name);
418 model_real_plain_vector lambda_full(mf_mult.
nb_basic_dof());
419 if (lambda.size()>0) mf_mult.extend_vector(lambda,lambda_full);
421 dal::bit_vector cc = master_cb.get_mesh().
422 region(GIVEN_CONTACT_REGION).index();
423 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).clear();
424 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).add(cc);
431 face_type face = master_cb.ext_face_of_elem(o);
433 master_cb.get_mesh().normal_of_face_of_convex(face.cv,face.f);
434 unit_face_normal/=gmm::vect_norm2(unit_face_normal);
435 scalar_type cosine_alpha = 0;
436 for (
size_type j = 0; j < dof_ls.size(); j++){
439 ls_grad_node[k]=normLS_master[dim*dof_ls[j]+k];
440 cosine_alpha += gmm::vect_sp(ls_grad_node,unit_face_normal);
442 cosine_alpha /= scalar_type(dof_ls.size());
443 scalar_type alpha = acos(cosine_alpha)*360/(2*M_PI);
446 scalar_type LS_extreeme = LS[dof_ls[0]];
447 if (master_cb.integration==master_contact_body::PER_ELEMENT)
448 for (
size_type j = 0; j < dof_ls.size(); j++)
449 LS_extreeme=std::min(LS[dof_ls[j]],LS_extreeme);
451 for (
size_type j = 0; j < dof_ls.size(); j++)
452 LS_extreeme=std::max(LS[dof_ls[j]],LS_extreeme);
454 scalar_type LM_sum = 0;
455 for (
size_type j = 0; j < dof_lm.size(); j++)
456 LM_sum+=lambda_full[dof_lm[j]];
458 const scalar_type TINY_2 = 1e-9;
460 if (LS_extreeme+LM_sum < TINY_2 || alpha > master_cb.max_contact_angle)
461 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).sup(o);
465 bool contact_surface_changed;
466 const dal::bit_vector& current_contact_elm_list =
467 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).index();
468 GMM_TRACE2(
"Current contact elements: "<< current_contact_elm_list);
469 GMM_TRACE2(
"Old contact elements: "<< old_contact_elm_list);
470 GMM_TRACE2(
"Pre-old contact elements: "<< pre_old_ct_list);
472 if (current_contact_elm_list == old_contact_elm_list &&
473 current_contact_elm_list.card() == old_contact_elm_list.card()) {
474 contact_surface_changed =
false;
475 GMM_TRACE2(
" the contact area has not changed");
477 if (current_contact_elm_list == pre_old_ct_list &&
478 current_contact_elm_list.card() == pre_old_ct_list.card()) {
479 contact_surface_changed =
false;
480 GMM_TRACE2(
" the contact area has changed, but cycling, \
481 so exiting active set search");
483 contact_surface_changed =
true;
484 GMM_TRACE2(
" the contact area has changed");
485 pre_old_ct_list = old_contact_elm_list;
486 old_contact_elm_list = current_contact_elm_list;
490 init_cont_detect_done =
true;
495 pmim_contact = master_cb.build_mesh_im_on_boundary(ACTIVE_CONTACT_REGION);
496 n_integrated_elems = pmim_contact->convex_index().card();
497 GMM_ASSERT1(n_integrated_elems==current_contact_elm_list.card(),
498 "Failure in integration method: The number of integrated elements "
499 "does not correspond to the number of contact elements");
501 return contact_surface_changed;
509 GMM_ASSERT1(master_cb.is_mesh_deformed(),
"Master mesh is not deformed, \
510 cannot calucalte contact info");
512 GMM_ASSERT1(slave_cb.is_mesh_deformed(),
"Slave mesh is not deformed, \
513 cannot calucalte contact info");
515 GMM_ASSERT1(master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).index().card()>0,
516 "Internal error: Contact area is empty");
519 pinterpolated_fem = std::make_shared<mesh_fem>(master_cb.get_mesh());
521 pinterpolated_fem_U = std::shared_ptr<mesh_fem>();
526 *pmim_contact, 0, dal::bit_vector(),
false);
527 pinterpolated_fem->set_finite_element(
528 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).index(),ifem_srf);
529 pinterpolated_fem->set_qdim(1);
533 pinterpolated_fem_U = std::make_shared<mesh_fem>(master_cb.get_mesh());
534 pinterpolated_fem_U->set_finite_element(master_cb.get_mesh().
535 region(ACTIVE_CONTACT_REGION).index(),ifem_srf);
536 pinterpolated_fem_U->set_qdim(master_cb.get_mesh().dim());
539 std::vector<size_type> index(pinterpolated_fem->nb_dof());
541 master_cb.get_mesh().region(ACTIVE_CONTACT_REGION).index();
542 for (dal::bv_visitor icv(cc); !icv.finished(); ++icv){
543 for (
size_type j = 0; j < pinterpolated_fem->nb_basic_dof_of_element(icv);
545 {index[pinterpolated_fem->ind_basic_dof_of_element(icv)[j]]
546 = ifem_srf->index_of_global_dof(icv, j);}
549 slave_ls_dofs = std::make_shared<gmm::unsorted_sub_index>(index);
552 std::vector<size_type> indexU(pinterpolated_fem_U->nb_dof());
553 size_type dim = pinterpolated_fem_U->get_qdim();
555 for(
size_type i=0;i<pinterpolated_fem->nb_dof();i++)
556 indexU[dim*i+d] = dim*index[i]+d;
557 slave_U_dofs = std::make_shared<gmm::unsorted_sub_index>(indexU);
559 members_are_computed=
true;
570 getfem::pbrick pbr = std::make_shared<level_set_contact_brick>(md,mcb,scb,rg);
573 const std::string& name_Um = mcb.get_var_name();
574 const std::string& name_Us = scb.get_var_name();
575 const std::string& name_LM = mcb.
get_pair_info(name_Us).get_mult_name();
576 model::termlist terms;
577 terms.push_back(model::term_description(name_Um,name_Um,
false));
578 terms.push_back(model::term_description(name_Us,name_Us,
false));
579 terms.push_back(model::term_description(name_LM,name_LM,
false));
580 terms.push_back(model::term_description(name_Um,name_Us,
true));
581 terms.push_back(model::term_description(name_Um,name_LM,
true));
582 terms.push_back(model::term_description(name_Us,name_LM,
true));
585 model::varnamelist variables;
586 variables.push_back(name_Um);
587 variables.push_back(name_Us);
588 variables.push_back(name_LM);
593 model::varnamelist datalist;
594 model::mimlist mimlist;
597 return md.
add_brick(pbr,variables,datalist,terms,mimlist,rg);
601 level_set_contact::level_set_contact_brick::
602 level_set_contact_brick(
604 master_contact_body& _mcb,
605 slave_contact_body& _scb,
607 md(_md),mcb(_mcb),scb(_scb), given_contact_id(rg)
609 GMM_ASSERT1(&md == &mcb.get_model(),
610 "Master body is defined on a different model then the input");
613 mcb.add_slave(scb,given_contact_id);
616 contact_region_id = mcb.get_pair_info(scb.get_var_name()).contact_region();
618 mcb.get_mesh().intersect_with_mpi_region(contact_region_);
619 contact_region_id = contact_region_.id();
622 set_flags(
"Level set contact brick",
633 const model::varnamelist &vl,
634 const model::varnamelist &,
635 const model::mimlist &,
636 model::real_matlist &matl,
637 model::real_veclist &vecl,
638 model::real_veclist &,
640 build_version version)
const {
642 GMM_ASSERT1(vl.size() == 3,
643 "Level set contact brick needs three variables");
644 GMM_ASSERT1(matl.size() == 6,
645 "Level set contact brick needs six matrices");
646 GMM_ASSERT1(vecl.size() == 6,
647 "Level set contact brick assembles size RHSs");
648 GMM_ASSERT1(region==given_contact_id,
649 "Assumed contact region has changed!!! \
650 This implementation does not handle this \
651 for efficiency reasons!!");
653 if (version & model::BUILD_MATRIX )
654 for(
size_type i=0;i<matl.size();i++) gmm::clear(matl[i]);
655 if (version & model::BUILD_RHS )
656 for(
size_type i=0;i<vecl.size();i++) gmm::clear(vecl[i]);
659 mcb.get_mesh().
region(contact_region_id);
660 if (active_contact_region.
index().card()==0)
return;
669 if (version & model::BUILD_MATRIX ) {
670 GMM_TRACE2(
"Level set contact brick stiffness matrix assembly on "
671 << mcb.
get_pair_info(scb.get_var_name()).num_of_integr_elems()
673 asm_level_set_contact_tangent_matrix(matl,mcb,scb,LM,active_contact_region);
677 if (version & model::BUILD_RHS ) {
678 GMM_TRACE2(
"Level set contact brick RHS assembly on "
679 << mcb.
get_pair_info(scb.get_var_name()).num_of_integr_elems()
681 asm_level_set_contact_rhs(vecl,mcb,scb,LM,active_contact_region);
683 gmm::scale(vecl[i], scalar_type(-1));
688 void level_set_contact::NormalTerm::compute(
690 bgeot::base_tensor &t)
693 size_type cv_volume = mcb.ext_face_of_elem(cv).cv;
697 un /= gmm::vect_norm2(un);
700 for (
size_type i = 0; i < dim; i++) t[i] = un[i];
704 if (i == j) t(i, j) = 1.0 - un[i] * un[j];
705 else t(i, j) =-un[i] * un[j];
710 level_set_contact::HFunction::HFunction(
711 const mesh_fem &lsmf_,
712 const plain_vector &LS_U_,
714 scalar_type small_h_):
723 const bgeot::multi_index& level_set_contact::HFunction::
726 void level_set_contact::HFunction::
730 bgeot::base_tensor &t)
737 plain_vector ls_interpolated(1);
738 ctx.
pf()->interpolation(ctx,U,ls_interpolated,1);
739 t[0] = hRegularized(ls_interpolated[0],m_Epsilon,small_h);
742 bgeot::scalar_type level_set_contact::HFunction::
743 hRegularized(scalar_type f, scalar_type epsilon, scalar_type small_h_)
745 if (f>epsilon)
return 1.0;
746 if (f<(-epsilon))
return small_h_;
747 return 0.5+0.125*(9.0*f/(epsilon)-5.0*pow(f/(epsilon),scalar_type(3)));
751 level_set_contact::Unity::Unity(
const mesh_fem &mf_):mf(mf_),sizes_(1)
753 const bgeot::multi_index& level_set_contact::Unity::sizes(
size_type)
const {
return sizes_;}
754 void level_set_contact::Unity::
756 void level_set_contact::Unity::
760 void level_set_contact::
766 const std::string& lsolver_name,
767 getfem::abstract_newton_line_search &ls)
769 bool active_set_converged =
false;
770 it_staggered.set_iteration(0);
775 it_newton.set_iteration(0);
776 getfem::rmodel_plsolver_type plsolver=getfem::select_linear_solver<sparse_matrix,plain_vector>(md,lsolver_name);
777 (*sf)(md,it_newton,plsolver,ls);
778 GMM_TRACE2(
"Newton converged? - "<<it_newton.converged());
779 GMM_TRACE2(
"active set converged? - "<<active_set_converged);
780 GMM_ASSERT1(it_newton.converged(),
"Newton method did not converge");
783 }
while(!active_set_converged &&
784 !it_staggered.finished(it_staggered.get_resmax()+1.0));
786 if (active_set_converged && it_newton.converged()) it_staggered.enforce_converged();
794 std::stringstream fname;
795 fname<<name.substr(0,5);
796 GMM_ASSERT1((fname.str()==
"GT_QK" || fname.str()==
"GT_PK"),
797 "Cannot handle other transformations but QK or PK,\
798 Sorry, to be implemented" );
799 std::stringstream str1(name.substr(6,1));
803 std::istringstream str2(name.substr(8,1));
807 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.