15#include "metaphysicl/metaphysicl_version.h"
16#include "metaphysicl/dualsemidynamicsparsenumberarray.h"
17#include "metaphysicl/parallel_dualnumber.h"
18#if METAPHYSICL_MAJOR_VERSION < 2
19#include "metaphysicl/parallel_dynamic_std_array_wrapper.h"
21#include "metaphysicl/parallel_dynamic_array_wrapper.h"
23#include "metaphysicl/parallel_semidynamicsparsenumberarray.h"
34 const auto & disp_x_name = ret.
get<std::vector<VariableName>>(
"disp_x");
35 if (disp_x_name.size() != 1)
36 mooseError(
"We require that the disp_x parameter have exactly one coupled name");
39 ret.
set<VariableName>(
"secondary_variable") = disp_x_name[0];
40 ret.
set<VariableName>(
"primary_variable") = disp_x_name[0];
51 params.
addParam<Real>(
"c_t", 1e0,
"Numerical parameter for tangential constraints");
55 "Minimum value of contact pressure that will trigger frictional enforcement");
57 "mu",
"mu > 0",
"The friction coefficient for the Coulomb friction law");
58 MooseEnum friction_projection_degree(
"ONE TWO",
"TWO");
59 friction_projection_degree.addDocumentation(
60 "ONE",
"Use the degree-one Alart-Curnier friction residual.");
61 friction_projection_degree.addDocumentation(
62 "TWO",
"Use the degree-two Hueber-Stadler-Wohlmuth friction residual.");
64 "friction_projection_degree",
65 friction_projection_degree,
66 "Degree of the friction-residual projection; see MortarContactUtils.h.");
73 _c_t(getParam<Real>(
"c_t")),
74 _friction_projection_degree(getParam<
MooseEnum>(
"friction_projection_degree")
75 .getEnum<
Moose::Mortar::Contact::FrictionProjectionDegree>()),
76 _secondary_x_dot(adCoupledDot(
"disp_x")),
77 _primary_x_dot(adCoupledNeighborValueDot(
"disp_x")),
78 _secondary_y_dot(adCoupledDot(
"disp_y")),
79 _primary_y_dot(adCoupledNeighborValueDot(
"disp_y")),
80 _secondary_z_dot(_has_disp_z ? &adCoupledDot(
"disp_z") : nullptr),
81 _primary_z_dot(_has_disp_z ? &adCoupledNeighborValueDot(
"disp_z") : nullptr),
82 _mu(getParam<Real>(
"mu")),
83 _epsilon(getParam<Real>(
"epsilon"))
95 const auto & secondary_ip_lowerd_map =
99 std::array<ADReal, 3> primary_disp_dot{
101 std::array<ADReal, 3> secondary_disp_dot{
107 const ADReal & prim_x_dot = primary_disp_dot[0];
108 const ADReal & prim_y_dot = primary_disp_dot[1];
109 const ADReal * prim_z_dot =
nullptr;
111 prim_z_dot = &primary_disp_dot[2];
113 const ADReal & sec_x_dot = secondary_disp_dot[0];
114 const ADReal & sec_y_dot = secondary_disp_dot[1];
115 const ADReal * sec_z_dot =
nullptr;
117 sec_z_dot = &secondary_disp_dot[2];
123 relative_velocity = {sec_x_dot - prim_x_dot, sec_y_dot - prim_y_dot, *sec_z_dot - *prim_z_dot};
125 relative_velocity = {sec_x_dot - prim_x_dot, sec_y_dot - prim_y_dot, 0.0};
137 const DofObject *
const dof =
168 const DofObject *
const dof = pr.first;
187 const std::unordered_set<const Node *> & inactive_lm_nodes)
197 const DofObject *
const dof = pr.first;
200 if ((inactive_lm_nodes.find(
static_cast<const Node *
>(dof)) != inactive_lm_nodes.end()) ||
217 const DofObject *
const dof)
219 using std::abs, std::sqrt, std::min;
227 const Real scaling_factor_x =
_lm_vars[0]->scalingFactor();
228 const Real scaling_factor_y =
_lm_vars[1]->scalingFactor();
229 Real scaling_factor_z = 1;
237 dof_id_type dof_index_z(-1);
244 scaling_factor_z =
_lm_vars[2]->scalingFactor();
247 ADReal normal_pressure_value =
249 ADReal tangential_pressure_value =
252 ADReal tangential_pressure_value_dir;
263 ADReal normal_dof_residual = min(normal_pressure_value, weighted_gap *
c);
264 ADReal tangential_dof_residual;
265 ADReal tangential_dof_residual_dir;
269 const std::array<ADReal, 1> tangential_pressure{{tangential_pressure_value}};
272 tangential_dof_residual =
277 normal_pressure_value,
285 const std::array<ADReal, 2> tangential_pressure{
286 {tangential_pressure_value, tangential_pressure_value_dir}};
287 const std::array<ADReal, 2> tangential_velocity{
290 const auto residual =
295 normal_pressure_value,
300 tangential_dof_residual = residual[0];
301 tangential_dof_residual_dir = residual[1];
323 unsigned int component_normal = 0;
326 const Real threshold_for_Jacobian =
_has_disp_z ? 1.0 / sqrt(3.0) : 1.0 / sqrt(2.0);
328 if (abs(ny) > threshold_for_Jacobian)
329 component_normal = 1;
330 else if (abs(nz) > threshold_for_Jacobian)
331 component_normal = 2;
335 std::array<ADReal, 1>{{normal_dof_residual}},
336 std::array<dof_id_type, 1>{{component_normal == 0
338 : (component_normal == 1 ? dof_index_y : dof_index_z)}},
339 component_normal == 0 ? scaling_factor_x
340 : (component_normal == 1 ? scaling_factor_y : scaling_factor_z));
344 std::array<ADReal, 1>{{tangential_dof_residual}},
345 std::array<dof_id_type, 1>{
346 {(component_normal == 0 || component_normal == 2) ? dof_index_y : dof_index_x}},
347 (component_normal == 0 || component_normal == 2) ? scaling_factor_y : scaling_factor_x);
352 std::array<ADReal, 1>{{tangential_dof_residual_dir}},
353 std::array<dof_id_type, 1>{
354 {(component_normal == 0 || component_normal == 1) ? dof_index_z : dof_index_x}},
355 (component_normal == 0 || component_normal == 1) ? scaling_factor_z : scaling_factor_x);
DualNumber< Real, DNDerivativeType, true > ADReal
void mooseError(Args &&... args)
std::map< unsigned int, unsigned int > getSecondaryIpToLowerElementMap(const Elem &lower_secondary_elem) const
std::map< unsigned int, unsigned int > getPrimaryIpToLowerElementMap(const Elem &primary_elem, const Elem &primary_elem_ip, const Elem &lower_secondary_elem) const
std::array< MooseUtils::SemidynamicVector< Point, 9 >, 2 > getNodalTangents(const Elem &secondary_elem) const
const MooseArray< Real > & _coord
const VariableTestValue & _test
Elem const *const & _lower_secondary_elem
const AutomaticMortarGeneration & amg() const
Elem const *const & _lower_primary_elem
static void trimInteriorNodeDerivatives(const std::map< unsigned int, unsigned int > &primary_ip_lowerd_map, const Variables &moose_var, DualNumbers &ad_vars, const bool is_secondary)
const std::vector< Real > & _JxW_msm
virtual const NumericVector< Number > *const & currentSolution() const=0
unsigned int number() const
void addResidualsAndJacobian(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
const Parallel::Communicator & _communicator
processor_id_type processor_id() const
void derivInsert(SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< N > > &derivs, libMesh::dof_id_type index, Real value)