www.mooseframework.org
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 ()
 

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 24 of file ContactMaster.h.

Constructor & Destructor Documentation

◆ ContactMaster()

ContactMaster::ContactMaster ( const InputParameters &  parameters)

Definition at line 72 of file ContactMaster.C.

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

Member Function Documentation

◆ addPoints()

void ContactMaster::addPoints ( )
overridevirtual

Definition at line 163 of file ContactMaster.C.

164 {
165  _point_to_info.clear();
166 
167  std::map<dof_id_type, PenetrationInfo *>::iterator
168  it = _penetration_locator._penetration_info.begin(),
169  end = _penetration_locator._penetration_info.end();
170 
171  for (; it != end; ++it)
172  {
173  PenetrationInfo * pinfo = it->second;
174 
175  // Skip this pinfo if there are no DOFs on this node.
176  if (!pinfo || pinfo->_node->n_comp(_sys.number(), _vars[_component]) < 1)
177  continue;
178 
179  bool is_nonlinear =
180  _subproblem.getMooseApp().getExecutioner()->feProblem().computingNonlinearResid();
181 
182  if (_component == 0)
183  computeContactForce(pinfo, is_nonlinear);
184 
185  if (pinfo->isCaptured())
186  {
187  addPoint(pinfo->_elem, pinfo->_closest_point);
188  _point_to_info[pinfo->_closest_point] = pinfo;
189  }
190  }
191 }

◆ computeContactForce()

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

Definition at line 194 of file ContactMaster.C.

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

Referenced by addPoints().

◆ computeQpJacobian()

Real ContactMaster::computeQpJacobian ( )
overridevirtual

Definition at line 342 of file ContactMaster.C.

343 {
344 
345  PenetrationInfo * pinfo = _point_to_info[_current_point];
346  Real penalty = _penalty;
347  if (_normalize_penalty)
348  penalty *= nodalArea(*pinfo);
349 
350  switch (_model)
351  {
353  switch (_formulation)
354  {
356  return 0;
357  break;
360  return _test[_i][_qp] * penalty * _phi[_j][_qp] * pinfo->_normal(_component) *
361  pinfo->_normal(_component);
362  break;
363  default:
364  mooseError("Invalid contact formulation");
365  break;
366  }
367  break;
368  case ContactModel::GLUED:
370  switch (_formulation)
371  {
373  return 0;
374  break;
377  return _test[_i][_qp] * penalty * _phi[_j][_qp];
378  break;
379  default:
380  mooseError("Invalid contact formulation");
381  break;
382  }
383  break;
384  default:
385  mooseError("Invalid or unavailable contact model");
386  break;
387  }
388 
389  return 0;
390  /*
391  if (_i != _j)
392  return 0;
393 
394  Node * node = pinfo->_node;
395 
396  RealVectorValue jac_vec;
397 
398  // Build up jac vector
399  for (unsigned int i=0; i<_dim; i++)
400  {
401  long int dof_number = node->dof_number(0, _vars[i], 0);
402  jac_vec(i) = _jacobian_copy(dof_number, dof_number);
403  }
404 
405  Real jac_mag = pinfo->_normal * jac_vec;
406 
407  return _test[_i][_qp]*pinfo->_normal(_component)*jac_mag;
408  */
409 }

◆ computeQpResidual()

Real ContactMaster::computeQpResidual ( )
overridevirtual

Definition at line 334 of file ContactMaster.C.

335 {
336  PenetrationInfo * pinfo = _point_to_info[_current_point];
337  Real resid = -pinfo->_contact_force(_component);
338  return _test[_i][_qp] * resid;
339 }

◆ getPenalty()

Real ContactMaster::getPenalty ( PenetrationInfo &  pinfo)
protected

Definition at line 430 of file ContactMaster.C.

431 {
432  Real penalty = _penalty;
433  if (_normalize_penalty)
434  penalty *= nodalArea(pinfo);
435 
436  return penalty;
437 }

Referenced by computeContactForce().

◆ nodalArea()

Real ContactMaster::nodalArea ( PenetrationInfo &  pinfo)
protected

Definition at line 412 of file ContactMaster.C.

413 {
414  const Node * node = pinfo._node;
415 
416  dof_id_type dof = node->dof_number(_aux_system.number(), _nodal_area_var->number(), 0);
417 
418  Real area = (*_aux_solution)(dof);
419  if (area == 0.0)
420  {
421  if (_t_step > 1)
422  mooseError("Zero nodal area found");
423  else
424  area = 1.0; // Avoid divide by zero during initialization
425  }
426  return area;
427 }

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

◆ timestepSetup()

void ContactMaster::timestepSetup ( )
overridevirtual

Definition at line 132 of file ContactMaster.C.

133 {
134  if (_component == 0)
136 }

◆ updateContactStatefulData()

void ContactMaster::updateContactStatefulData ( )
virtual

Definition at line 139 of file ContactMaster.C.

140 {
141  std::map<dof_id_type, PenetrationInfo *>::iterator
142  it = _penetration_locator._penetration_info.begin(),
143  end = _penetration_locator._penetration_info.end();
144  for (; it != end; ++it)
145  {
146  PenetrationInfo * pinfo = it->second;
147 
148  // Skip this pinfo if there are no DOFs on this node.
149  if (!pinfo || pinfo->_node->n_comp(_sys.number(), _vars[_component]) < 1)
150  continue;
151 
152  pinfo->_locked_this_step = 0;
153  pinfo->_starting_elem = it->second->_elem;
154  pinfo->_starting_side_num = it->second->_side_num;
155  pinfo->_starting_closest_point_ref = it->second->_closest_point_ref;
156  pinfo->_contact_force_old = pinfo->_contact_force;
157  pinfo->_accumulated_slip_old = pinfo->_accumulated_slip;
158  pinfo->_frictional_energy_old = pinfo->_frictional_energy;
159  }
160 }

Referenced by timestepSetup().

Member Data Documentation

◆ _aux_solution

const NumericVector<Number>* ContactMaster::_aux_solution
protected

Definition at line 63 of file ContactMaster.h.

◆ _aux_system

SystemBase& ContactMaster::_aux_system
protected

Definition at line 62 of file ContactMaster.h.

Referenced by nodalArea().

◆ _capture_tolerance

const Real ContactMaster::_capture_tolerance
protected

Definition at line 51 of file ContactMaster.h.

Referenced by computeContactForce().

◆ _component

const unsigned int ContactMaster::_component
protected

◆ _formulation

const ContactFormulation ContactMaster::_formulation
protected

Definition at line 44 of file ContactMaster.h.

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

◆ _friction_coefficient

const Real ContactMaster::_friction_coefficient
protected

Definition at line 49 of file ContactMaster.h.

Referenced by computeContactForce(), and ContactMaster().

◆ _mesh_dimension

const unsigned int ContactMaster::_mesh_dimension
protected

Definition at line 57 of file ContactMaster.h.

Referenced by computeContactForce().

◆ _model

const ContactModel ContactMaster::_model
protected

Definition at line 43 of file ContactMaster.h.

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

◆ _nodal_area_var

MooseVariable* ContactMaster::_nodal_area_var
protected

Definition at line 61 of file ContactMaster.h.

Referenced by nodalArea().

◆ _normalize_penalty

const bool ContactMaster::_normalize_penalty
protected

Definition at line 45 of file ContactMaster.h.

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

◆ _penalty

const Real ContactMaster::_penalty
protected

Definition at line 48 of file ContactMaster.h.

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

◆ _penetration_locator

PenetrationLocator& ContactMaster::_penetration_locator
protected

Definition at line 46 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 55 of file ContactMaster.h.

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

◆ _residual_copy

NumericVector<Number>& ContactMaster::_residual_copy
protected

Definition at line 53 of file ContactMaster.h.

Referenced by computeContactForce().

◆ _tension_release

const Real ContactMaster::_tension_release
protected

Definition at line 50 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:
ContactMaster::_component
const unsigned int _component
Definition: ContactMaster.h:42
ContactModel::GLUED
ContactMaster::_aux_system
SystemBase & _aux_system
Definition: ContactMaster.h:62
ContactMaster::_penetration_locator
PenetrationLocator & _penetration_locator
Definition: ContactMaster.h:46
ContactMaster::_aux_solution
const NumericVector< Number > * _aux_solution
Definition: ContactMaster.h:63
ContactMaster::_residual_copy
NumericVector< Number > & _residual_copy
Definition: ContactMaster.h:53
ContactMaster::_point_to_info
std::map< Point, PenetrationInfo * > _point_to_info
Definition: ContactMaster.h:55
ContactFormulation::KINEMATIC
ContactMaster::_formulation
const ContactFormulation _formulation
Definition: ContactMaster.h:44
ContactMaster::nodalArea
Real nodalArea(PenetrationInfo &pinfo)
Definition: ContactMaster.C:412
ContactMaster::_vars
std::vector< unsigned int > _vars
Definition: ContactMaster.h:59
ContactMaster::_tension_release
const Real _tension_release
Definition: ContactMaster.h:50
ContactModel::COULOMB
ContactMaster::_capture_tolerance
const Real _capture_tolerance
Definition: ContactMaster.h:51
ContactModel::FRICTIONLESS
ContactMaster::_normalize_penalty
const bool _normalize_penalty
Definition: ContactMaster.h:45
ContactMaster::_nodal_area_var
MooseVariable * _nodal_area_var
Definition: ContactMaster.h:61
ContactMaster::computeContactForce
void computeContactForce(PenetrationInfo *pinfo, bool update_contact_set)
Definition: ContactMaster.C:194
ContactMaster::getPenalty
Real getPenalty(PenetrationInfo &pinfo)
Definition: ContactMaster.C:430
ContactMaster::_mesh_dimension
const unsigned int _mesh_dimension
Definition: ContactMaster.h:57
ContactMaster::_friction_coefficient
const Real _friction_coefficient
Definition: ContactMaster.h:49
ContactFormulation::AUGMENTED_LAGRANGE
ContactMaster::_penalty
const Real _penalty
Definition: ContactMaster.h:48
ContactMaster::_model
const ContactModel _model
Definition: ContactMaster.h:43
ContactMaster::updateContactStatefulData
virtual void updateContactStatefulData()
Definition: ContactMaster.C:139
ContactFormulation::PENALTY