11 #include "PenetrationLocator.h"
12 #include "PenetrationInfo.h"
13 #include "SystemBase.h"
15 #include "NearestNodeLocator.h"
16 #include "MooseVariableFE.h"
18 #include "libmesh/numeric_vector.h"
19 #include "libmesh/enum_fe_family.h"
27 InputParameters params = validParams<NodeFaceConstraint>();
28 params.set<
bool>(
"use_displaced_mesh") =
true;
31 params.addRequiredParam<MooseEnum>(
32 "component",
component,
"The force component constraint that this object is supplying");
33 params.addRequiredCoupledVar(
35 "The displacements appropriate for the simulation geometry and coordinate system");
36 params.addClassDescription(
"Applies the Reduced Active Nonlinear Function Set scheme in which "
37 "the slave node's non-linear residual function is replaced by the "
38 "zero penetration constraint equation when the constraint is active");
43 : NodeFaceConstraint(parameters),
44 _component(getParam<MooseEnum>(
"component")),
45 _mesh_dimension(_mesh.dimension()),
46 _residual_copy(_sys.residualGhosted()),
47 _dof_number_to_value(coupledComponents(
"displacements")),
48 _disp_coupling(coupledComponents(
"displacements"))
51 for (
unsigned int i = 0; i < coupledComponents(
"displacements"); ++i)
53 _vars.push_back(coupled(
"displacements", i));
58 if (var->feType().family != LAGRANGE)
59 mooseError(
"This object only works when the displacement variables use a Lagrange basis");
62 mooseError(
"The number of displacement variables does not match the mesh dimension!");
68 auto system_coupling_matrix = _subproblem.couplingMatrix();
70 for (MooseIndex(
_vars) i = 0; i <
_vars.size(); ++i)
71 for (MooseIndex(
_vars) j = 0; j <
_vars.size(); ++j)
87 NodeFaceConstraint::residualSetup();
102 std::map<dof_id_type, PenetrationInfo *>::iterator found =
103 _penetration_locator._penetration_info.find(_current_node->id());
104 if (found != _penetration_locator._penetration_info.end())
111 if (!_subproblem.currentlyComputingJacobian())
117 dof_id_type dof_number = _current_node->dof_number(0,
_vars[i], 0);
126 std::vector<dof_id_type> cols;
127 std::vector<Number> values;
134 "Somehow the sizes of our variable containers got out of sync");
137 auto slave_dof_number = _current_node->dof_number(0,
_vars[i], 0);
139 _jacobian->get_row(slave_dof_number, cols, values);
140 mooseAssert(cols.size() == values.size(),
141 "The size of the dof container and value container are different");
143 for (MooseIndex(cols) j = 0; j < cols.size(); ++j)
145 std::make_pair(cols[j], values[j] /
_var_objects[i]->scalingFactor()));
150 "The node " << _current_node->id()
151 <<
" should map to a contact lagrange multiplier");
153 "The node " << _current_node->id()
154 <<
" should map to a tied lagrange multiplier");
168 if (_subproblem.computingNonlinearResid())
172 _current_master ==
_pinfo->_elem,
173 "The current master element and the PenetrationInfo object's element should "
175 master_elem_sequence.push_back(
_pinfo->_elem);
182 if (master_elem_sequence.size() >= 5 &&
183 _pinfo->_elem == *(master_elem_sequence.rbegin() + 2) &&
184 _pinfo->_elem == *(master_elem_sequence.rbegin() + 4) &&
185 _pinfo->_elem != *(master_elem_sequence.rbegin() + 1) &&
186 *(master_elem_sequence.rbegin() + 1) == *(master_elem_sequence.rbegin() + 3))
190 _penetration_locator._nearest_node.nearestNode(_current_node->id());
193 mooseAssert(
_pinfo->_elem->get_node_index(master_node) != libMesh::invalid_uint,
194 "The master node is not on the current element");
195 mooseAssert((*(master_elem_sequence.rbegin() + 1))->get_node_index(master_node) !=
196 libMesh::invalid_uint,
197 "The master node is not on the other ping-ponging element");
200 std::make_pair(_current_node->id(), master_node));
219 "nearest node not a node on the current master element");
233 auto largest_component_magnitude = std::abs(
_pinfo->_normal(0));
237 auto component_magnitude = std::abs(
_pinfo->_normal(i));
238 if (component_magnitude > largest_component_magnitude)
240 largest_component_magnitude = component_magnitude;
263 case Moose::ConstraintType::Slave:
272 "We should be selecting the largest normal component, hence it should be "
273 "impossible for this normal component to be zero");
284 case Moose::ConstraintType::Master:
307 case Moose::ConstraintJacobianType::SlaveSlave:
310 return _phi_slave[_j][_qp];
331 "The connected dof index is not found in the _dof_number_to_value container. "
332 "This must mean that insufficient sparsity was allocated");
341 case Moose::ConstraintJacobianType::SlaveMaster:
368 case Moose::ConstraintJacobianType::MasterSlave:
376 "The connected dof index is not found in the _dof_number_to_value container. "
377 "This must mean that insufficient sparsity was allocated");
394 "The connected dof index is not found in the _dof_number_to_value container. "
395 "This must mean that insufficient sparsity was allocated");
421 mooseError(
"We overrode commputeSlaveValue so computeQpSlaveValue should never get called");