18#include "libmesh/numeric_vector.h"
19#include "libmesh/enum_fe_family.h"
27 params.
set<
bool>(
"use_displaced_mesh") =
true;
31 "component", component,
"The force component constraint that this object is supplying");
34 "The displacements appropriate for the simulation geometry and coordinate system");
35 params.
addParam<
bool>(
"ping_pong_protection",
37 "Whether to protect against ping-ponging, e.g. the oscillation of the "
38 "secondary node between two "
39 "different primary faces, by tying the secondary node to the "
40 "edge between the involved primary faces");
42 "normal_smoothing_distance",
43 "Distance from edge in parametric coordinates over which to smooth contact normal");
44 params.
addClassDescription(
"Applies the Reduced Active Nonlinear Function Set scheme in which "
45 "the secondary node's non-linear residual function is replaced by the "
46 "zero penetration constraint equation when the constraint is active");
52 _component(getParam<
MooseEnum>(
"component")),
53 _mesh_dimension(_mesh.dimension()),
54 _residual_copy(_sys.residualGhosted()),
55 _dof_number_to_value(coupledComponents(
"displacements")),
56 _disp_coupling(coupledComponents(
"displacements")),
57 _ping_pong_protection(getParam<bool>(
"ping_pong_protection"))
67 if (var->feType().family != LAGRANGE)
68 mooseError(
"This object only works when the displacement variables use a Lagrange basis");
71 mooseError(
"The number of displacement variables does not match the mesh dimension!");
82 for (MooseIndex(
_vars) i = 0; i <
_vars.size(); ++i)
83 for (MooseIndex(
_vars) j = 0; j <
_vars.size(); ++j)
114 std::map<dof_id_type, PenetrationInfo *>::iterator found =
138 std::vector<dof_id_type> cols;
139 std::vector<Number>
values;
146 "Somehow the sizes of our variable containers got out of sync");
152 mooseAssert(cols.size() ==
values.size(),
153 "The size of the dof container and value container are different");
155 for (MooseIndex(cols) j = 0; j < cols.size(); ++j)
163 <<
" should map to a contact lagrange multiplier");
166 <<
" should map to a tied lagrange multiplier");
185 "The current primary element and the PenetrationInfo object's element should "
195 _pinfo->
_elem == *(primary_elem_sequence.rbegin() + 2) &&
196 _pinfo->
_elem == *(primary_elem_sequence.rbegin() + 4) &&
197 _pinfo->
_elem != *(primary_elem_sequence.rbegin() + 1) &&
198 *(primary_elem_sequence.rbegin() + 1) == *(primary_elem_sequence.rbegin() + 3))
206 "The primary node is not on the current element");
207 mooseAssert((*(primary_elem_sequence.rbegin() + 1))->get_node_index(primary_node) !=
209 "The primary node is not on the other ping-ponging element");
231 "nearest node not a node on the current primary element");
245 auto largest_component_magnitude = std::abs(
_pinfo->
_normal(0));
250 if (component_magnitude > largest_component_magnitude)
252 largest_component_magnitude = component_magnitude;
275 case Moose::ConstraintType::Secondary:
284 "We should be selecting the largest normal component, hence it should be "
285 "impossible for this normal component to be zero");
296 case Moose::ConstraintType::Primary:
319 case Moose::ConstraintJacobianType::SecondarySecondary:
343 "The connected dof index is not found in the _dof_number_to_value container. "
344 "This must mean that insufficient sparsity was allocated");
353 case Moose::ConstraintJacobianType::SecondaryPrimary:
380 case Moose::ConstraintJacobianType::PrimarySecondary:
388 "The connected dof index is not found in the _dof_number_to_value container. "
389 "This must mean that insufficient sparsity was allocated");
406 "The connected dof index is not found in the _dof_number_to_value container. "
407 "This must mean that insufficient sparsity was allocated");
434 "We overrode commputeSecondaryValue so computeQpSecondaryValue should never get called");
std::array< Real, 2 > values
MooseVariable * getVar(const std::string &var_name, unsigned int comp)
unsigned int coupledComponents(const std::string &var_name) const
virtual unsigned int coupled(const std::string &var_name, unsigned int comp=0) const
const InputParameters & parameters() const
const std::string & type() const
void mooseError(Args &&... args) const
const Node * nearestNode(dof_id_type node_id)
PenetrationLocator & _penetration_locator
const Node *const & _current_node
void residualSetup() override
const Elem *const & _current_primary
std::vector< dof_id_type > _connected_dof_indices
const VariableTestValue & _test_primary
const SparseMatrix< Number > * _jacobian
static InputParameters validParams()
const VariablePhiValue & _phi_primary
VariablePhiValue _phi_secondary
void setNormalSmoothingDistance(Real normal_smoothing_distance)
std::map< dof_id_type, PenetrationInfo * > & _penetration_info
NearestNodeLocator & _nearest_node
const bool & currentlyComputingJacobian() const
bool computingNonlinearResid() const
virtual const libMesh::CouplingMatrix * couplingMatrix(const unsigned int nl_sys_num) const=0
unsigned int number() const
virtual void insert(const T *v, const std::vector< numeric_index_type > &dof_indices)
virtual void get_row(numeric_index_type i, std::vector< numeric_index_type > &indices, std::vector< T > &values) const=0
const unsigned int invalid_uint