17 #include "metaphysicl/metaphysicl_version.h" 18 #include "metaphysicl/dualsemidynamicsparsenumberarray.h" 19 #include "metaphysicl/parallel_dualnumber.h" 20 #if METAPHYSICL_MAJOR_VERSION < 2 21 #include "metaphysicl/parallel_dynamic_std_array_wrapper.h" 23 #include "metaphysicl/parallel_dynamic_array_wrapper.h" 25 #include "metaphysicl/parallel_semidynamicsparsenumberarray.h" 36 params.
addClassDescription(
"Computes the tangential frictional forces for dynamic simulations");
39 "The frictional Lagrange's multiplier for an addtional direction.");
42 "Coupled function to evaluate friction with values from contact pressure and relative " 43 "tangential velocities (from the previous step).");
44 params.
addParam<
Real>(
"c_t", 1e0,
"Numerical parameter for tangential constraints");
48 "Minimum value of contact pressure that will trigger frictional enforcement");
49 params.
addParam<
Real>(
"mu",
"The friction coefficient for the Coulomb friction law");
56 _c_t(getParam<
Real>(
"c_t")),
57 _secondary_x_dot(_secondary_var.adUDot()),
58 _primary_x_dot(_primary_var.adUDotNeighbor()),
59 _secondary_y_dot(adCoupledDot(
"disp_y")),
60 _primary_y_dot(adCoupledNeighborValueDot(
"disp_y")),
61 _secondary_z_dot(_has_disp_z ? &adCoupledDot(
"disp_z") : nullptr),
62 _primary_z_dot(_has_disp_z ? &adCoupledNeighborValueDot(
"disp_z") : nullptr),
63 _epsilon(getParam<
Real>(
"epsilon")),
64 _mu(isParamValid(
"mu") ? getParam<
Real>(
"mu") :
std::numeric_limits<double>::quiet_NaN()),
65 _function_friction(isParamValid(
"function_friction") ? &getFunction(
"function_friction")
67 _has_friction_function(isParamValid(
"function_friction")),
72 "A coefficient of friction needs to be provided as a constant value of via a function.");
76 "Either provide a constant coefficient of friction or a function defining the " 77 "coefficient of friction. Both inputs cannot be provided simultaneously.");
79 if (!getParam<bool>(
"use_displaced_mesh"))
81 "'use_displaced_mesh' must be true for the " 82 "ComputeFrictionalForceLMMechanicalContact object");
86 "Three-dimensional mortar frictional contact simulations require an additional " 87 "frictional Lagrange's multiplier to enforce a second tangential pressure");
98 "Frictional contact constraints only support elemental variables of CONSTANT order");
125 const DofObject *
const dof =
135 nodal_tangents[0][
_i];
145 nodal_tangents[1][
_i];
185 const DofObject *
const dof = pr.first;
210 const std::unordered_set<const Node *> & inactive_lm_nodes)
224 const DofObject *
const dof = pr.first;
227 if ((inactive_lm_nodes.find(static_cast<const Node *>(dof)) != inactive_lm_nodes.end()) ||
248 const DofObject *
const dof)
250 using std::max, std::sqrt;
260 std::array<dof_id_type, 2> friction_dof_indices;
261 std::array<ADReal, 2> friction_lm_values;
263 const unsigned int num_tangents = 2;
288 dof_residual = friction_lm_values[0];
289 dof_residual_dir = friction_lm_values[1];
293 const Real epsilon_sqrt = 1.0e-48;
295 const auto lamdba_plus_cg = contact_pressure +
c * weighted_gap;
296 std::array<ADReal, 2> lambda_t_plus_ctu;
297 lambda_t_plus_ctu[0] = friction_lm_values[0] + c_t * *tangential_vel[0] *
_dt;
298 lambda_t_plus_ctu[1] = friction_lm_values[1] + c_t * *tangential_vel[1] *
_dt;
300 const auto term_1_x =
max(mu_ad * lamdba_plus_cg,
301 sqrt(lambda_t_plus_ctu[0] * lambda_t_plus_ctu[0] +
302 lambda_t_plus_ctu[1] * lambda_t_plus_ctu[1] + epsilon_sqrt)) *
303 friction_lm_values[0];
305 const auto term_1_y =
max(mu_ad * lamdba_plus_cg,
306 sqrt(lambda_t_plus_ctu[0] * lambda_t_plus_ctu[0] +
307 lambda_t_plus_ctu[1] * lambda_t_plus_ctu[1] + epsilon_sqrt)) *
308 friction_lm_values[1];
310 const auto term_2_x = mu_ad *
max(0.0, lamdba_plus_cg) * lambda_t_plus_ctu[0];
312 const auto term_2_y = mu_ad *
max(0.0, lamdba_plus_cg) * lambda_t_plus_ctu[1];
314 dof_residual = term_1_x - term_2_x;
315 dof_residual_dir = term_1_y - term_2_y;
319 std::array<ADReal, 1>{{dof_residual}},
320 std::array<dof_id_type, 1>{{friction_dof_indices[0]}},
323 std::array<ADReal, 1>{{dof_residual_dir}},
324 std::array<dof_id_type, 1>{{friction_dof_indices[1]}},
330 const DofObject *
const dof)
332 using std::max, std::abs;
359 dof_residual = friction_lm_value;
362 const auto term_1 =
max(mu_ad * (contact_pressure +
c * weighted_gap),
363 abs(friction_lm_value + c_t * tangential_vel *
_dt)) *
365 const auto term_2 = mu_ad *
max(0.0, contact_pressure +
c * weighted_gap) *
366 (friction_lm_value + c_t * tangential_vel *
_dt);
368 dof_residual = term_1 - term_2;
372 std::array<ADReal, 1>{{dof_residual}},
373 std::array<dof_id_type, 1>{{friction_dof_index}},
379 const ADReal & contact_pressure,
const Real & tangential_vel,
const Real & tangential_vel_dir)
390 ADReal tangential_vel_magnitude =
391 sqrt(tangential_vel * tangential_vel + tangential_vel_dir * tangential_vel_dir + 1.0e-24);
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
virtual const NumericVector< Number > *const & currentSolution() const=0
void addResidualsAndJacobian(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
void paramError(const std::string ¶m, Args... args) const
unsigned int number() const
MooseVariable * getVar(const std::string &var_name, unsigned int comp)
const std::vector< Real > & _JxW_msm
const Parallel::Communicator & _communicator
DualNumber< Real, DNDerivativeType, true > ADReal
auto max(const L &left, const R &right)
const VariableTestValue & _test
Elem const *const & _lower_secondary_elem
const AutomaticMortarGeneration & amg() const
std::array< MooseUtils::SemidynamicVector< Point, 9 >, 2 > getNodalTangents(const Elem &secondary_elem) const
unsigned int number() const
MooseVariable *const _var
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
void derivInsert(SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< N >> &derivs, libMesh::dof_id_type index, Real value)
bool isParamValid(const std::string &name) const
virtual Real value(Real t, const Point &p) const
const MooseArray< Real > & _coord
NumericVector< Number > & solutionOld()
processor_id_type processor_id() const