12 #include "SystemBase.h"
13 #include "PenetrationLocator.h"
16 #include "libmesh/string_to_enum.h"
17 #include "libmesh/sparse_matrix.h"
28 params.addRequiredParam<BoundaryName>(
"boundary",
"The master boundary");
29 params.addRequiredParam<BoundaryName>(
"slave",
"The slave boundary");
30 params.addRequiredParam<
unsigned int>(
"component",
31 "An integer corresponding to the direction "
32 "the variable this kernel acts in. (0 for x, "
35 params.addCoupledVar(
"disp_x",
"The x displacement");
36 params.addCoupledVar(
"disp_y",
"The y displacement");
37 params.addCoupledVar(
"disp_z",
"The z displacement");
41 "The displacements appropriate for the simulation geometry and coordinate system");
43 params.addRequiredCoupledVar(
"nodal_area",
"The nodal area");
45 params.set<
bool>(
"use_displaced_mesh") =
true;
46 params.addParam<Real>(
49 "The penalty to apply. This can vary depending on the stiffness of your materials");
50 params.addParam<Real>(
"friction_coefficient", 0.0,
"The friction coefficient");
51 params.addParam<Real>(
"tangential_tolerance",
52 "Tangential distance to extend edges of contact surfaces");
53 params.addParam<Real>(
"tension_release",
55 "Tension release threshold. A node in contact "
56 "will not be released if its tensile load is below "
57 "this value. Must be positive.");
64 _component(getParam<unsigned int>(
"component")),
65 _model(getParam<MooseEnum>(
"model").getEnum<
ContactModel>()),
67 _penalty(getParam<Real>(
"penalty")),
68 _friction_coefficient(getParam<Real>(
"friction_coefficient")),
69 _tension_release(getParam<Real>(
"tension_release")),
70 _updateContactSet(true),
71 _residual_copy(_sys.residualGhosted()),
72 _vars(3,
libMesh::invalid_uint),
73 _nodal_area_var(getVar(
"nodal_area", 0)),
74 _aux_system(_nodal_area_var->sys()),
75 _aux_solution(_aux_system.currentSolution())
77 if (parameters.isParamValid(
"tangential_tolerance"))
78 _penetration_locator.setTangentialTolerance(getParam<Real>(
"tangential_tolerance"));
80 if (parameters.isParamValid(
"normal_smoothing_distance"))
81 _penetration_locator.setNormalSmoothingDistance(getParam<Real>(
"normal_smoothing_distance"));
83 if (parameters.isParamValid(
"normal_smoothing_method"))
84 _penetration_locator.setNormalSmoothingMethod(
85 parameters.get<MooseEnum>(
"normal_smoothing_method"));
87 if (isParamValid(
"displacements"))
90 for (
unsigned int i = 0; i < coupledComponents(
"displacements"); ++i)
91 _vars[i] = coupled(
"displacements", i);
96 if (isParamValid(
"disp_x"))
97 _vars[0] = coupled(
"disp_x");
98 if (isParamValid(
"disp_y"))
99 _vars[1] = coupled(
"disp_y");
100 if (isParamValid(
"disp_z"))
101 _vars[2] = coupled(
"disp_z");
103 mooseDeprecated(
"use the `displacements` parameter rather than the `disp_*` parameters (those "
104 "will go away with the deprecation of the Solid Mechanics module).");
107 _penetration_locator.setUpdate(
false);
135 auto & has_penetrated = _penetration_locator._has_penetrated;
137 for (
auto & pinfo_pair : _penetration_locator._penetration_info)
139 PenetrationInfo * pinfo = pinfo_pair.second;
142 if (!pinfo || pinfo->_node->n_comp(_sys.number(),
_vars[
_component]) < 1)
145 const dof_id_type slave_node_num = pinfo_pair.first;
146 auto hpit = has_penetrated.find(slave_node_num);
148 if (beginning_of_step)
150 pinfo->_starting_elem = pinfo->_elem;
151 pinfo->_starting_side_num = pinfo->_side_num;
152 pinfo->_starting_closest_point_ref = pinfo->_closest_point_ref;
155 if (pinfo->_distance >= 0)
156 if (hpit == has_penetrated.end())
157 has_penetrated.insert(slave_node_num);
164 auto hpit = _penetration_locator._has_penetrated.find(_current_node->id());
165 return hpit != _penetration_locator._has_penetrated.end();
171 return _u_slave[_qp];
181 PenetrationInfo * pinfo = _penetration_locator._penetration_info[_current_node->id()];
183 Real pen_force =
_penalty * distance;
185 Real resid = pen_force;
187 pinfo->_mech_status = PenetrationInfo::MS_STICKING;
189 return _test_slave[_i][_qp] * resid;
194 PenetrationInfo * pinfo = _penetration_locator._penetration_info[_current_node->id()];
196 dof_id_type dof_number = _current_node->dof_number(0,
_vars[
_component], 0);
200 pinfo->_mech_status = PenetrationInfo::MS_STICKING;
202 return _test_master[_i][_qp] * resid;
214 case Moose::SlaveSlave:
215 return _penalty * _phi_slave[_j][_qp] * _test_slave[_i][_qp];
217 case Moose::SlaveMaster:
218 return _penalty * -_phi_master[_j][_qp] * _test_slave[_i][_qp];
220 case Moose::MasterSlave:
222 const double slave_jac = (*_jacobian)(_current_node->dof_number(0,
_vars[
_component], 0),
223 _connected_dof_indices[_j]);
224 return slave_jac * _test_master[_i][_qp];
227 case Moose::MasterMaster:
231 mooseError(
"Unhandled ConstraintJacobianType");
245 case Moose::SlaveSlave:
246 case Moose::SlaveMaster:
247 case Moose::MasterMaster:
250 case Moose::MasterSlave:
252 const double slave_jac = (*_jacobian)(_current_node->dof_number(0,
_vars[
_component], 0),
253 _connected_dof_indices[_j]);
254 retVal = slave_jac * _test_master[_i][_qp];
259 mooseError(
"Unhandled ConstraintJacobianType");