26 #include "libmesh/id_types.h" 27 #include "libmesh/string_to_enum.h" 28 #include "libmesh/sparse_matrix.h" 42 params.
addParam<BoundaryName>(
"secondary",
"The secondary boundary");
44 "An integer corresponding to the direction " 45 "the variable this constraint acts on. (0 for x, " 49 "The displacements appropriate for the simulation geometry and coordinate system");
50 params.
addCoupledVar(
"secondary_gap_offset",
"offset to the gap distance from secondary side");
52 "offset to the gap distance mapped from primary side");
53 params.
set<
bool>(
"use_displaced_mesh") =
true;
56 "The penalty to apply. Its optimal value can vary depending on the " 57 "stiffness of the materials");
58 params.
addParam<
Real>(
"friction_coefficient", 0,
"The friction coefficient");
60 "Tangential distance to extend edges of contact surfaces");
62 "print_contact_nodes",
false,
"Whether to print the number of nodes in contact.");
65 "Apply non-penetration constraints on the mechanical deformation in explicit dynamics " 66 "using a node on face formulation by solving uncoupled momentum-balance equations.");
74 _displaced_problem(parameters.
get<
FEProblemBase *>(
"_fe_problem_base")->getDisplacedProblem()),
75 _component(getParam<unsigned
int>(
"component")),
77 _update_stateful_data(true),
78 _mesh_dimension(_mesh.dimension()),
80 _var_objects(3, nullptr),
81 _has_secondary_gap_offset(isCoupled(
"secondary_gap_offset")),
82 _secondary_gap_offset_var(_has_secondary_gap_offset ? getVar(
"secondary_gap_offset", 0)
84 _has_mapped_primary_gap_offset(isCoupled(
"mapped_primary_gap_offset")),
85 _mapped_primary_gap_offset_var(
86 _has_mapped_primary_gap_offset ? getVar(
"mapped_primary_gap_offset", 0) : nullptr),
87 _penalty(getParam<
Real>(
"penalty")),
88 _print_contact_nodes(getParam<bool>(
"print_contact_nodes")),
89 _residual_copy(_sys.residualGhosted()),
90 _gap_rate(&writableVariable(
"gap_rate")),
91 _neighbor_vel_x(isCoupled(
"vel_x") ? coupledNeighborValue(
"vel_x") : _zero),
92 _neighbor_vel_y(isCoupled(
"vel_y") ? coupledNeighborValue(
"vel_y") : _zero),
93 _neighbor_vel_z((_mesh.dimension() == 3 && isCoupled(
"vel_z")) ? coupledNeighborValue(
"vel_z")
126 "Velocities vel_x and vel_y (also vel_z in three dimensions) need to be provided " 127 "for the 'balance' option of solving normal contact in explicit dynamics.");
154 if (beginning_of_step)
158 pinfo->_contact_force_old = pinfo->_contact_force;
159 pinfo->_accumulated_slip_old = pinfo->_accumulated_slip;
160 pinfo->_frictional_energy_old = pinfo->_frictional_energy;
161 pinfo->_mech_status_old = pinfo->_mech_status;
166 mooseWarning(
"Previous step did not converge. Check results");
173 pinfo->_starting_elem = pinfo->_elem;
174 pinfo->_starting_side_num = pinfo->_side_num;
175 pinfo->_starting_closest_point_ref = pinfo->_closest_point_ref;
177 pinfo->_incremental_slip_prev_iter = pinfo->_incremental_slip;
187 bool in_contact =
false;
189 std::map<dof_id_type, PenetrationInfo *>::iterator found =
194 if (pinfo !=
nullptr)
212 bool update_contact_set)
224 distance_vec += udotvec;
226 if (distance_vec.
norm() != 0)
229 const Real gap_size = -1.0 * pinfo->
_normal * distance_vec;
233 bool newly_captured =
false;
236 if (update_contact_set && !pinfo->
isCaptured() &&
239 newly_captured =
true;
259 mooseError(
"Invalid or unavailable contact model");
263 if (update_contact_set && pinfo->
isCaptured() && !newly_captured)
266 if (-contact_pressure >= 0.0)
290 const auto & diag =
_sys.
getVector(
"mass_matrix_diag_inverted");
292 Real mass_node = 1.0 / diag(dof_x);
295 Real mass_eff = (mass_face * mass_node) / (mass_face + mass_node);
310 n_velocity_x, n_velocity_y,
_mesh.
dimension() == 3 ? n_velocity_z : 0.0);
312 Real gap_rate = pinfo->
_normal * (secondary_velocity - closest_point_velocity);
325 gap_rate = pinfo->
_normal * (secondary_velocity - closest_point_velocity);
387 std::vector<dof_id_type> face_dofs;
391 for (
const auto dof : face_dofs)
392 mass_face += 1.0 / lumped_mass(dof);
394 mass_face /= face_dofs.size();
virtual bool isCoupled(const std::string &var_name, unsigned int i=0) const
const unsigned int & neighborSide() const
virtual unsigned int coupled(const std::string &var_name, unsigned int comp=0) const
auto norm() const -> decltype(std::norm(Real()))
const unsigned int invalid_uint
void setNormalSmoothingDistance(Real normal_smoothing_distance)
MooseVariable & _primary_var
const Elem *const & _current_primary
virtual void setNodalValue(const Real &value, unsigned int idx=0)=0
static const std::string velocity_z
static InputParameters validParams()
MooseVariable * getVar(const std::string &var_name, unsigned int comp)
static const std::string velocity_x
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
const VariableTestValue & _test_primary
std::map< dof_id_type, PenetrationInfo *> & _penetration_info
void setTangentialTolerance(Real tangential_tolerance)
virtual const Node & nodeRef(const dof_id_type i) const
void mooseWarning(Args &&... args) const
const Node *const & _current_node
bool isParamValid(const std::string &name) const
virtual void getDofIndices(const Elem *elem, std::vector< dof_id_type > &dof_indices) const override
virtual unsigned int dimension() const
virtual NumericVector< Number > * solutionUDot()
FEProblemBase & _fe_problem
const std::string & type() const
const VariableValue & _u_secondary
static const std::string velocity_y
void paramError(const std::string ¶m, Args... args) const
unsigned int number() const
RealVectorValue _contact_force
Executioner * getExecutioner() const
OutputData getNodalValue(const Node &node) const
VariableTestValue _test_secondary
unsigned int coupledComponents(const std::string &var_name) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const std::set< SubdomainID > EMPTY_BLOCK_IDS
static InputParameters validParams()
bool absoluteFuzzyGreaterEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
void mooseError(Args &&... args) const
const InputParameters & parameters() const
bool _overwrite_secondary_residual
void setNormalSmoothingMethod(std::string nsmString)
virtual bool lastSolveConverged() const=0
PenetrationLocator & _penetration_locator
processor_id_type processor_id() const
virtual NumericVector< Number > & getVector(const std::string &name)
void ErrorVector unsigned int
const Elem & get(const ElemType type_in)