www.mooseframework.org
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
ContactMaster Class Reference

#include <ContactMaster.h>

Inheritance diagram for ContactMaster:
[legend]

Public Member Functions

 ContactMaster (const InputParameters &parameters)
 
virtual void timestepSetup () override
 
virtual void addPoints () override
 
void computeContactForce (PenetrationInfo *pinfo, bool update_contact_set)
 
virtual Real computeQpResidual () override
 
virtual Real computeQpJacobian () override
 
virtual void updateContactStatefulData ()
 

Static Public Member Functions

static ContactFormulation contactFormulation (std::string name)
 
static ContactModel contactModel (std::string name)
 

Protected Member Functions

Real nodalArea (PenetrationInfo &pinfo)
 
Real getPenalty (PenetrationInfo &pinfo)
 

Protected Attributes

const unsigned int _component
 
const ContactModel _model
 
const ContactFormulation _formulation
 
const bool _normalize_penalty
 
PenetrationLocator & _penetration_locator
 
const Real _penalty
 
const Real _friction_coefficient
 
const Real _tension_release
 
const Real _capture_tolerance
 
NumericVector< Number > & _residual_copy
 
std::map< Point, PenetrationInfo * > _point_to_info
 
const unsigned int _mesh_dimension
 
std::vector< unsigned int > _vars
 
MooseVariable * _nodal_area_var
 
SystemBase & _aux_system
 
const NumericVector< Number > * _aux_solution
 

Detailed Description

Definition at line 35 of file ContactMaster.h.

Constructor & Destructor Documentation

◆ ContactMaster()

ContactMaster::ContactMaster ( const InputParameters &  parameters)

Definition at line 79 of file ContactMaster.C.

80  : DiracKernel(parameters),
81  _component(getParam<unsigned int>("component")),
82  _model(contactModel(getParam<std::string>("model"))),
83  _formulation(contactFormulation(getParam<std::string>("formulation"))),
84  _normalize_penalty(getParam<bool>("normalize_penalty")),
86  getPenetrationLocator(getParam<BoundaryName>("boundary"),
87  getParam<BoundaryName>("slave"),
88  Utility::string_to_enum<Order>(getParam<MooseEnum>("order")))),
89  _penalty(getParam<Real>("penalty")),
90  _friction_coefficient(getParam<Real>("friction_coefficient")),
91  _tension_release(getParam<Real>("tension_release")),
92  _capture_tolerance(getParam<Real>("capture_tolerance")),
93  _residual_copy(_sys.residualGhosted()),
94  _mesh_dimension(_mesh.dimension()),
95  _vars(3, libMesh::invalid_uint),
96  _nodal_area_var(getVar("nodal_area", 0)),
98  _aux_solution(_aux_system.currentSolution())
99 {
100  if (isParamValid("displacements"))
101  {
102  // modern parameter scheme for displacements
103  for (unsigned int i = 0; i < coupledComponents("displacements"); ++i)
104  _vars[i] = coupled("displacements", i);
105  }
106  else
107  {
108  // Legacy parameter scheme for displacements
109  if (isParamValid("disp_x"))
110  _vars[0] = coupled("disp_x");
111  if (isParamValid("disp_y"))
112  _vars[1] = coupled("disp_y");
113  if (isParamValid("disp_z"))
114  _vars[2] = coupled("disp_z");
115 
116  mooseDeprecated("use the `displacements` parameter rather than the `disp_*` parameters (those "
117  "will go away with the deprecation of the Solid Mechanics module).");
118  }
119 
120  if (parameters.isParamValid("tangential_tolerance"))
121  _penetration_locator.setTangentialTolerance(getParam<Real>("tangential_tolerance"));
122 
123  if (parameters.isParamValid("normal_smoothing_distance"))
124  _penetration_locator.setNormalSmoothingDistance(getParam<Real>("normal_smoothing_distance"));
125 
126  if (parameters.isParamValid("normal_smoothing_method"))
127  _penetration_locator.setNormalSmoothingMethod(
128  parameters.get<std::string>("normal_smoothing_method"));
129 
131  _penetration_locator.setUpdate(false);
132 
133  if (_friction_coefficient < 0)
134  mooseError("The friction coefficient must be nonnegative");
135 }
MooseVariable * _nodal_area_var
Definition: ContactMaster.h:75
const Real _tension_release
Definition: ContactMaster.h:64
const NumericVector< Number > * _aux_solution
Definition: ContactMaster.h:77
SystemBase & _aux_system
Definition: ContactMaster.h:76
const Real _friction_coefficient
Definition: ContactMaster.h:63
const ContactFormulation _formulation
Definition: ContactMaster.h:58
const unsigned int _mesh_dimension
Definition: ContactMaster.h:71
const unsigned int _component
Definition: ContactMaster.h:56
NumericVector< Number > & _residual_copy
Definition: ContactMaster.h:67
const Real _penalty
Definition: ContactMaster.h:62
const Real _capture_tolerance
Definition: ContactMaster.h:65
const bool _normalize_penalty
Definition: ContactMaster.h:59
PenetrationLocator & _penetration_locator
Definition: ContactMaster.h:60
static ContactFormulation contactFormulation(std::string name)
static ContactModel contactModel(std::string name)
const ContactModel _model
Definition: ContactMaster.h:57
std::vector< unsigned int > _vars
Definition: ContactMaster.h:73

Member Function Documentation

◆ addPoints()

void ContactMaster::addPoints ( )
overridevirtual

Definition at line 169 of file ContactMaster.C.

170 {
171  _point_to_info.clear();
172 
173  std::map<dof_id_type, PenetrationInfo *>::iterator
174  it = _penetration_locator._penetration_info.begin(),
175  end = _penetration_locator._penetration_info.end();
176 
177  for (; it != end; ++it)
178  {
179  PenetrationInfo * pinfo = it->second;
180 
181  // Skip this pinfo if there are no DOFs on this node.
182  if (!pinfo || pinfo->_node->n_comp(_sys.number(), _vars[_component]) < 1)
183  continue;
184 
185  bool is_nonlinear =
186  _subproblem.getMooseApp().getExecutioner()->feProblem().computingNonlinearResid();
187 
188  if (_component == 0)
189  computeContactForce(pinfo, is_nonlinear);
190 
191  if (pinfo->isCaptured())
192  {
193  addPoint(pinfo->_elem, pinfo->_closest_point);
194  _point_to_info[pinfo->_closest_point] = pinfo;
195  }
196  }
197 }
const unsigned int _component
Definition: ContactMaster.h:56
void computeContactForce(PenetrationInfo *pinfo, bool update_contact_set)
std::map< Point, PenetrationInfo * > _point_to_info
Definition: ContactMaster.h:69
PenetrationLocator & _penetration_locator
Definition: ContactMaster.h:60
std::vector< unsigned int > _vars
Definition: ContactMaster.h:73

◆ computeContactForce()

void ContactMaster::computeContactForce ( PenetrationInfo *  pinfo,
bool  update_contact_set 
)

Definition at line 200 of file ContactMaster.C.

Referenced by addPoints().

201 {
202  const Node * node = pinfo->_node;
203 
204  RealVectorValue res_vec;
205  // Build up residual vector
206  for (unsigned int i = 0; i < _mesh_dimension; ++i)
207  {
208  dof_id_type dof_number = node->dof_number(0, _vars[i], 0);
209  res_vec(i) = _residual_copy(dof_number);
210  }
211 
212  RealVectorValue distance_vec(_mesh.nodeRef(node->id()) - pinfo->_closest_point);
213  const Real gap_size = -1. * pinfo->_normal * distance_vec;
214 
215  // This is for preventing an increment of pinfo->_locked_this_step for nodes that are
216  // captured and released in this function
217  bool newly_captured = false;
218 
219  // Capture
220  if (update_contact_set && !pinfo->isCaptured() &&
221  MooseUtils::absoluteFuzzyGreaterEqual(gap_size, 0, _capture_tolerance))
222  {
223  newly_captured = true;
224  pinfo->capture();
225 
226  // Increment the lock count every time the node comes back into contact from not being in
227  // contact.
228  if (_formulation == CF_KINEMATIC)
229  ++pinfo->_locked_this_step;
230  }
231 
232  if (!pinfo->isCaptured())
233  return;
234 
235  const Real area = nodalArea(*pinfo);
236 
237  RealVectorValue pen_force(_penalty * distance_vec);
238  if (_normalize_penalty)
239  pen_force *= area;
240 
241  if (_model == CM_FRICTIONLESS)
242  {
243  switch (_formulation)
244  {
245  case CF_DEFAULT:
246  pinfo->_contact_force = -pinfo->_normal * (pinfo->_normal * res_vec);
247  break;
248  case CF_PENALTY:
249  pinfo->_contact_force = pinfo->_normal * (pinfo->_normal * pen_force);
250  break;
252  pinfo->_contact_force =
253  (pinfo->_normal *
254  (pinfo->_normal * (pen_force + pinfo->_lagrange_multiplier * pinfo->_normal)));
255  break;
256  default:
257  mooseError("Invalid contact formulation");
258  break;
259  }
260  pinfo->_mech_status = PenetrationInfo::MS_SLIPPING;
261  }
262  else if (_model == CM_COULOMB && _formulation == CF_PENALTY)
263  {
264  distance_vec =
265  pinfo->_incremental_slip +
266  (pinfo->_normal * (_mesh.nodeRef(node->id()) - pinfo->_closest_point)) * pinfo->_normal;
267  pen_force = _penalty * distance_vec;
268  if (_normalize_penalty)
269  pen_force *= area;
270 
271  // Frictional capacity
272  // const Real capacity( _friction_coefficient * (pen_force * pinfo->_normal < 0 ? -pen_force *
273  // pinfo->_normal : 0) );
274  const Real capacity(_friction_coefficient *
275  (res_vec * pinfo->_normal > 0 ? res_vec * pinfo->_normal : 0));
276 
277  // Elastic predictor
278  pinfo->_contact_force =
279  pen_force +
280  (pinfo->_contact_force_old - pinfo->_normal * (pinfo->_normal * pinfo->_contact_force_old));
281  RealVectorValue contact_force_normal((pinfo->_contact_force * pinfo->_normal) * pinfo->_normal);
282  RealVectorValue contact_force_tangential(pinfo->_contact_force - contact_force_normal);
283 
284  // Tangential magnitude of elastic predictor
285  const Real tan_mag(contact_force_tangential.norm());
286 
287  if (tan_mag > capacity)
288  {
289  pinfo->_contact_force = contact_force_normal + capacity * contact_force_tangential / tan_mag;
290  pinfo->_mech_status = PenetrationInfo::MS_SLIPPING;
291  }
292  else
293  {
294  pinfo->_mech_status = PenetrationInfo::MS_STICKING;
295  }
296  }
297  else if (_model == CM_GLUED || (_model == CM_COULOMB && _formulation == CF_DEFAULT))
298  {
299  switch (_formulation)
300  {
301  case CF_DEFAULT:
302  pinfo->_contact_force = -res_vec;
303  break;
304  case CF_PENALTY:
305  pinfo->_contact_force = pen_force;
306  break;
308  pinfo->_contact_force =
309  pen_force + pinfo->_lagrange_multiplier * distance_vec / distance_vec.norm();
310  break;
311  default:
312  mooseError("Invalid contact formulation");
313  break;
314  }
315  pinfo->_mech_status = PenetrationInfo::MS_STICKING;
316  }
317  else
318  {
319  mooseError("Invalid or unavailable contact model");
320  }
321 
322  // Release
323  if (update_contact_set && _model != CM_GLUED && pinfo->isCaptured() && !newly_captured &&
324  _tension_release >= 0 && pinfo->_locked_this_step < 2)
325  {
326  const Real contact_pressure = -(pinfo->_normal * pinfo->_contact_force) / area;
327  if (-contact_pressure >= _tension_release)
328  {
329  pinfo->release();
330  pinfo->_contact_force.zero();
331  }
332  }
333 
334  if (_formulation == CF_AUGMENTED_LAGRANGE && pinfo->isCaptured())
335  pinfo->_lagrange_multiplier -= getPenalty(*pinfo) * gap_size;
336 }
const Real _tension_release
Definition: ContactMaster.h:64
Real getPenalty(PenetrationInfo &pinfo)
const Real _friction_coefficient
Definition: ContactMaster.h:63
const ContactFormulation _formulation
Definition: ContactMaster.h:58
const unsigned int _mesh_dimension
Definition: ContactMaster.h:71
NumericVector< Number > & _residual_copy
Definition: ContactMaster.h:67
const Real _penalty
Definition: ContactMaster.h:62
const Real _capture_tolerance
Definition: ContactMaster.h:65
const bool _normalize_penalty
Definition: ContactMaster.h:59
const ContactModel _model
Definition: ContactMaster.h:57
std::vector< unsigned int > _vars
Definition: ContactMaster.h:73
Real nodalArea(PenetrationInfo &pinfo)

◆ computeQpJacobian()

Real ContactMaster::computeQpJacobian ( )
overridevirtual

Definition at line 347 of file ContactMaster.C.

348 {
349 
350  PenetrationInfo * pinfo = _point_to_info[_current_point];
351  Real penalty = _penalty;
352  if (_normalize_penalty)
353  penalty *= nodalArea(*pinfo);
354 
355  switch (_model)
356  {
357  case CM_FRICTIONLESS:
358  switch (_formulation)
359  {
360  case CF_DEFAULT:
361  return 0;
362  break;
363  case CF_PENALTY:
365  return _test[_i][_qp] * penalty * _phi[_j][_qp] * pinfo->_normal(_component) *
366  pinfo->_normal(_component);
367  break;
368  default:
369  mooseError("Invalid contact formulation");
370  break;
371  }
372  break;
373  case CM_GLUED:
374  case CM_COULOMB:
375  switch (_formulation)
376  {
377  case CF_DEFAULT:
378  return 0;
379  break;
380  case CF_PENALTY:
382  return _test[_i][_qp] * penalty * _phi[_j][_qp];
383  break;
384  default:
385  mooseError("Invalid contact formulation");
386  break;
387  }
388  break;
389  default:
390  mooseError("Invalid or unavailable contact model");
391  break;
392  }
393 
394  return 0;
395  /*
396  if (_i != _j)
397  return 0;
398 
399  Node * node = pinfo->_node;
400 
401  RealVectorValue jac_vec;
402 
403  // Build up jac vector
404  for (unsigned int i=0; i<_dim; i++)
405  {
406  long int dof_number = node->dof_number(0, _vars[i], 0);
407  jac_vec(i) = _jacobian_copy(dof_number, dof_number);
408  }
409 
410  Real jac_mag = pinfo->_normal * jac_vec;
411 
412  return _test[_i][_qp]*pinfo->_normal(_component)*jac_mag;
413  */
414 }
const ContactFormulation _formulation
Definition: ContactMaster.h:58
const unsigned int _component
Definition: ContactMaster.h:56
const Real _penalty
Definition: ContactMaster.h:62
std::map< Point, PenetrationInfo * > _point_to_info
Definition: ContactMaster.h:69
const bool _normalize_penalty
Definition: ContactMaster.h:59
const ContactModel _model
Definition: ContactMaster.h:57
Real nodalArea(PenetrationInfo &pinfo)

◆ computeQpResidual()

Real ContactMaster::computeQpResidual ( )
overridevirtual

Definition at line 339 of file ContactMaster.C.

340 {
341  PenetrationInfo * pinfo = _point_to_info[_current_point];
342  Real resid = -pinfo->_contact_force(_component);
343  return _test[_i][_qp] * resid;
344 }
const unsigned int _component
Definition: ContactMaster.h:56
std::map< Point, PenetrationInfo * > _point_to_info
Definition: ContactMaster.h:69

◆ contactFormulation()

ContactFormulation ContactMaster::contactFormulation ( std::string  name)
static

Definition at line 435 of file ContactMaster.C.

436 {
437  ContactFormulation formulation(CF_INVALID);
438  std::transform(name.begin(), name.end(), name.begin(), ::tolower);
439 
440  if ("default" == name || "kinematic" == name)
441  formulation = CF_DEFAULT;
442 
443  else if ("penalty" == name)
444  formulation = CF_PENALTY;
445 
446  else if ("augmented_lagrange" == name)
447  formulation = CF_AUGMENTED_LAGRANGE;
448 
449  else if ("tangential_penalty" == name)
450  formulation = CF_TANGENTIAL_PENALTY;
451 
452  if (formulation == CF_INVALID)
453  ::mooseError("Invalid formulation found: ", name);
454 
455  return formulation;
456 }
ContactFormulation
Definition: ContactMaster.h:25
const std::string name
Definition: Setup.h:22

◆ contactModel()

ContactModel ContactMaster::contactModel ( std::string  name)
static

Definition at line 417 of file ContactMaster.C.

418 {
419  ContactModel model(CM_INVALID);
420  std::transform(name.begin(), name.end(), name.begin(), ::tolower);
421 
422  if ("frictionless" == name)
423  model = CM_FRICTIONLESS;
424  else if ("glued" == name)
425  model = CM_GLUED;
426  else if ("coulomb" == name)
427  model = CM_COULOMB;
428  else
429  ::mooseError("Invalid contact model found: ", name);
430 
431  return model;
432 }
ContactModel
Definition: ContactMaster.h:17
const std::string name
Definition: Setup.h:22

◆ getPenalty()

Real ContactMaster::getPenalty ( PenetrationInfo &  pinfo)
protected

Definition at line 477 of file ContactMaster.C.

Referenced by computeContactForce().

478 {
479  Real penalty = _penalty;
480  if (_normalize_penalty)
481  penalty *= nodalArea(pinfo);
482 
483  return penalty;
484 }
const Real _penalty
Definition: ContactMaster.h:62
const bool _normalize_penalty
Definition: ContactMaster.h:59
Real nodalArea(PenetrationInfo &pinfo)

◆ nodalArea()

Real ContactMaster::nodalArea ( PenetrationInfo &  pinfo)
protected

Definition at line 459 of file ContactMaster.C.

Referenced by computeContactForce(), computeQpJacobian(), and getPenalty().

460 {
461  const Node * node = pinfo._node;
462 
463  dof_id_type dof = node->dof_number(_aux_system.number(), _nodal_area_var->number(), 0);
464 
465  Real area = (*_aux_solution)(dof);
466  if (area == 0.0)
467  {
468  if (_t_step > 1)
469  mooseError("Zero nodal area found");
470  else
471  area = 1.0; // Avoid divide by zero during initialization
472  }
473  return area;
474 }
MooseVariable * _nodal_area_var
Definition: ContactMaster.h:75
SystemBase & _aux_system
Definition: ContactMaster.h:76

◆ timestepSetup()

void ContactMaster::timestepSetup ( )
overridevirtual

Definition at line 138 of file ContactMaster.C.

139 {
140  if (_component == 0)
142 }
const unsigned int _component
Definition: ContactMaster.h:56
virtual void updateContactStatefulData()

◆ updateContactStatefulData()

void ContactMaster::updateContactStatefulData ( )
virtual

Definition at line 145 of file ContactMaster.C.

Referenced by timestepSetup().

146 {
147  std::map<dof_id_type, PenetrationInfo *>::iterator
148  it = _penetration_locator._penetration_info.begin(),
149  end = _penetration_locator._penetration_info.end();
150  for (; it != end; ++it)
151  {
152  PenetrationInfo * pinfo = it->second;
153 
154  // Skip this pinfo if there are no DOFs on this node.
155  if (!pinfo || pinfo->_node->n_comp(_sys.number(), _vars[_component]) < 1)
156  continue;
157 
158  pinfo->_locked_this_step = 0;
159  pinfo->_starting_elem = it->second->_elem;
160  pinfo->_starting_side_num = it->second->_side_num;
161  pinfo->_starting_closest_point_ref = it->second->_closest_point_ref;
162  pinfo->_contact_force_old = pinfo->_contact_force;
163  pinfo->_accumulated_slip_old = pinfo->_accumulated_slip;
164  pinfo->_frictional_energy_old = pinfo->_frictional_energy;
165  }
166 }
const unsigned int _component
Definition: ContactMaster.h:56
PenetrationLocator & _penetration_locator
Definition: ContactMaster.h:60
std::vector< unsigned int > _vars
Definition: ContactMaster.h:73

Member Data Documentation

◆ _aux_solution

const NumericVector<Number>* ContactMaster::_aux_solution
protected

Definition at line 77 of file ContactMaster.h.

◆ _aux_system

SystemBase& ContactMaster::_aux_system
protected

Definition at line 76 of file ContactMaster.h.

Referenced by nodalArea().

◆ _capture_tolerance

const Real ContactMaster::_capture_tolerance
protected

Definition at line 65 of file ContactMaster.h.

Referenced by computeContactForce().

◆ _component

const unsigned int ContactMaster::_component
protected

◆ _formulation

const ContactFormulation ContactMaster::_formulation
protected

Definition at line 58 of file ContactMaster.h.

Referenced by computeContactForce(), computeQpJacobian(), and ContactMaster().

◆ _friction_coefficient

const Real ContactMaster::_friction_coefficient
protected

Definition at line 63 of file ContactMaster.h.

Referenced by computeContactForce(), and ContactMaster().

◆ _mesh_dimension

const unsigned int ContactMaster::_mesh_dimension
protected

Definition at line 71 of file ContactMaster.h.

Referenced by computeContactForce().

◆ _model

const ContactModel ContactMaster::_model
protected

Definition at line 57 of file ContactMaster.h.

Referenced by computeContactForce(), computeQpJacobian(), and ContactMaster().

◆ _nodal_area_var

MooseVariable* ContactMaster::_nodal_area_var
protected

Definition at line 75 of file ContactMaster.h.

Referenced by nodalArea().

◆ _normalize_penalty

const bool ContactMaster::_normalize_penalty
protected

Definition at line 59 of file ContactMaster.h.

Referenced by computeContactForce(), computeQpJacobian(), and getPenalty().

◆ _penalty

const Real ContactMaster::_penalty
protected

Definition at line 62 of file ContactMaster.h.

Referenced by computeContactForce(), computeQpJacobian(), and getPenalty().

◆ _penetration_locator

PenetrationLocator& ContactMaster::_penetration_locator
protected

Definition at line 60 of file ContactMaster.h.

Referenced by addPoints(), ContactMaster(), and updateContactStatefulData().

◆ _point_to_info

std::map<Point, PenetrationInfo *> ContactMaster::_point_to_info
protected

Definition at line 69 of file ContactMaster.h.

Referenced by addPoints(), computeQpJacobian(), and computeQpResidual().

◆ _residual_copy

NumericVector<Number>& ContactMaster::_residual_copy
protected

Definition at line 67 of file ContactMaster.h.

Referenced by computeContactForce().

◆ _tension_release

const Real ContactMaster::_tension_release
protected

Definition at line 64 of file ContactMaster.h.

Referenced by computeContactForce().

◆ _vars

std::vector<unsigned int> ContactMaster::_vars
protected

The documentation for this class was generated from the following files: