13 #include "SystemBase.h"
14 #include "MooseMesh.h"
17 #include "libmesh/plane.h"
18 #include "libmesh/sparse_matrix.h"
19 #include "libmesh/string_to_enum.h"
27 InputParameters params = validParams<DiracKernel>();
30 params.addRequiredParam<BoundaryName>(
"boundary",
"The slave boundary");
31 params.addRequiredParam<BoundaryName>(
"master",
"The master boundary");
32 params.addRequiredParam<
unsigned int>(
"component",
33 "An integer corresponding to the direction "
34 "the variable this kernel acts in. (0 for x, "
37 params.addCoupledVar(
"disp_x",
"The x displacement");
38 params.addCoupledVar(
"disp_y",
"The y displacement");
39 params.addCoupledVar(
"disp_z",
"The z displacement");
43 "The displacements appropriate for the simulation geometry and coordinate system");
45 params.addRequiredCoupledVar(
"nodal_area",
"The nodal area");
47 params.set<
bool>(
"use_displaced_mesh") =
true;
48 params.addParam<Real>(
51 "The penalty to apply. This can vary depending on the stiffness of your materials");
52 params.addParam<Real>(
"friction_coefficient", 0,
"The friction coefficient");
53 params.addParam<Real>(
"tangential_tolerance",
54 "Tangential distance to extend edges of contact surfaces");
55 params.addParam<
bool>(
58 "Whether to normalize the penalty parameter with the nodal area for penalty contact.");
63 : DiracKernel(parameters),
64 _component(getParam<unsigned int>(
"component")),
65 _model(getParam<MooseEnum>(
"model").getEnum<
ContactModel>()),
67 _normalize_penalty(getParam<bool>(
"normalize_penalty")),
69 getPenetrationLocator(getParam<BoundaryName>(
"master"),
70 getParam<BoundaryName>(
"boundary"),
71 Utility::string_to_enum<Order>(getParam<MooseEnum>(
"order")))),
72 _penalty(getParam<Real>(
"penalty")),
73 _friction_coefficient(getParam<Real>(
"friction_coefficient")),
74 _residual_copy(_sys.residualGhosted()),
75 _vars(3,
libMesh::invalid_uint),
76 _mesh_dimension(_mesh.dimension()),
77 _nodal_area_var(getVar(
"nodal_area", 0)),
78 _aux_system(_nodal_area_var->sys()),
79 _aux_solution(_aux_system.currentSolution())
81 if (isParamValid(
"displacements"))
84 for (
unsigned int i = 0; i < coupledComponents(
"displacements"); ++i)
85 _vars[i] = coupled(
"displacements", i);
90 if (isParamValid(
"disp_x"))
91 _vars[0] = coupled(
"disp_x");
92 if (isParamValid(
"disp_y"))
93 _vars[1] = coupled(
"disp_y");
94 if (isParamValid(
"disp_z"))
95 _vars[2] = coupled(
"disp_z");
97 mooseDeprecated(
"use the `displacements` parameter rather than the `disp_*` parameters (those "
98 "will go away with the deprecation of the Solid Mechanics module).");
101 if (parameters.isParamValid(
"tangential_tolerance"))
104 if (parameters.isParamValid(
"normal_smoothing_distance"))
107 if (parameters.isParamValid(
"normal_smoothing_method"))
109 parameters.get<std::string>(
"normal_smoothing_method"));
117 std::map<dof_id_type, PenetrationInfo *>::iterator
121 const auto & node_to_elem_map = _mesh.nodeToElemMap();
122 for (; it != end; ++it)
124 PenetrationInfo * pinfo = it->second;
127 if (!pinfo || pinfo->_node->n_comp(_sys.number(),
_vars[
_component]) < 1)
130 dof_id_type slave_node_num = it->first;
131 const Node * node = pinfo->_node;
133 if (pinfo->isCaptured() && node->processor_id() == processor_id())
136 auto node_to_elem_pair = node_to_elem_map.find(slave_node_num);
137 mooseAssert(node_to_elem_pair != node_to_elem_map.end(),
"Missing node in node to elem map");
138 const std::vector<dof_id_type> & connected_elems = node_to_elem_pair->second;
142 for (
unsigned int i = 0; i < connected_elems.size() && !elem; ++i)
144 Elem * cur_elem = _mesh.elemPtr(connected_elems[i]);
145 if (cur_elem->processor_id() == processor_id())
150 "Couldn't find an element on this processor that is attached to the slave node!");
152 addPoint(elem, *node);
162 const Node * node = pinfo->_node;
164 Real resid = pinfo->_contact_force(
_component);
170 RealVectorValue distance_vec(_mesh.nodeRef(node->id()) - pinfo->_closest_point);
171 RealVectorValue pen_force(
_penalty * distance_vec);
176 resid += pinfo->_normal(
_component) * pinfo->_normal * pen_force;
182 return _test[_i][_qp] * resid;
193 const Node * node = pinfo->_node;
215 RealVectorValue normal(pinfo->_normal);
227 term = penalty * nnTDiag;
234 A2 = pinfo->_dxyzdeta[0];
235 d2 = pinfo->_d2xyzdxideta[0];
243 const RealVectorValue distance_vec(_mesh.nodeRef(node->id()) - pinfo->_closest_point);
244 const Real ATA11(A1 * A1);
245 const Real ATA12(A1 * A2);
246 const Real ATA22(A2 * A2);
247 const Real D11(-ATA11);
248 const Real D12(-ATA12 + d2 * distance_vec);
249 const Real D22(-ATA22);
256 const Real detD(D11 * D22 - D12 * D12);
258 invD12 = -D12 / detD;
266 const Real AinvD11(A1(0) * invD11 + A2(0) * invD12);
267 const Real AinvD12(A1(0) * invD12 + A2(0) * invD22);
268 const Real AinvD21(A1(1) * invD11 + A2(1) * invD12);
269 const Real AinvD22(A1(1) * invD12 + A2(1) * invD22);
270 const Real AinvD31(A1(2) * invD11 + A2(2) * invD12);
271 const Real AinvD32(A1(2) * invD12 + A2(2) * invD22);
273 const Real AinvDAT11(AinvD11 * A1(0) + AinvD12 * A2(0));
277 const Real AinvDAT22(AinvD21 * A1(1) + AinvD22 * A2(1));
281 const Real AinvDAT33(AinvD31 * A1(2) + AinvD32 * A2(2));
284 term += penalty * (1 - nnTDiag + AinvDAT11);
287 term += penalty * (1 - nnTDiag + AinvDAT22);
290 term += penalty * (1 - nnTDiag + AinvDAT33);
300 mooseError(
"Invalid or unavailable contact model");
303 return _test[_i][_qp] * term * _phi[_j][_qp];
309 const Node * node = pinfo._node;
313 Real area = (*_aux_solution)(dof);
317 mooseError(
"Zero nodal area found");