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");
64 _c_t(getParam<
Real>(
"c_t")),
65 _secondary_x_dot(adCoupledDot(
"disp_x")),
66 _primary_x_dot(adCoupledNeighborValueDot(
"disp_x")),
67 _secondary_y_dot(adCoupledDot(
"disp_y")),
68 _primary_y_dot(adCoupledNeighborValueDot(
"disp_y")),
69 _secondary_z_dot(_has_disp_z ? &adCoupledDot(
"disp_z") : nullptr),
70 _primary_z_dot(_has_disp_z ? &adCoupledNeighborValueDot(
"disp_z") : nullptr),
71 _mu(getParam<
Real>(
"mu")),
72 _epsilon(getParam<
Real>(
"epsilon"))
84 const auto & secondary_ip_lowerd_map =
88 std::array<ADReal, 3> primary_disp_dot{
90 std::array<ADReal, 3> secondary_disp_dot{
96 const ADReal & prim_x_dot = primary_disp_dot[0];
97 const ADReal & prim_y_dot = primary_disp_dot[1];
98 const ADReal * prim_z_dot =
nullptr;
100 prim_z_dot = &primary_disp_dot[2];
102 const ADReal & sec_x_dot = secondary_disp_dot[0];
103 const ADReal & sec_y_dot = secondary_disp_dot[1];
104 const ADReal * sec_z_dot =
nullptr;
106 sec_z_dot = &secondary_disp_dot[2];
112 relative_velocity = {sec_x_dot - prim_x_dot, sec_y_dot - prim_y_dot, *sec_z_dot - *prim_z_dot};
114 relative_velocity = {sec_x_dot - prim_x_dot, sec_y_dot - prim_y_dot, 0.0};
126 const DofObject *
const dof =
157 const DofObject *
const dof = pr.first;
176 const std::unordered_set<const Node *> & inactive_lm_nodes)
186 const DofObject *
const dof = pr.first;
189 if ((inactive_lm_nodes.find(static_cast<const Node *>(dof)) != inactive_lm_nodes.end()) ||
206 const DofObject *
const dof)
208 using std::abs, std::sqrt, std::max, std::min;
216 const Real scaling_factor_x =
_lm_vars[0]->scalingFactor();
217 const Real scaling_factor_y =
_lm_vars[1]->scalingFactor();
218 Real scaling_factor_z = 1;
233 scaling_factor_z =
_lm_vars[2]->scalingFactor();
236 ADReal normal_pressure_value =
238 ADReal tangential_pressure_value =
241 ADReal tangential_pressure_value_dir;
252 ADReal normal_dof_residual =
min(normal_pressure_value, weighted_gap *
c);
253 ADReal tangential_dof_residual;
254 ADReal tangential_dof_residual_dir;
261 if (normal_pressure_value.value() <
_epsilon)
262 tangential_dof_residual = tangential_pressure_value;
265 const auto term_1 =
max(
_mu * (normal_pressure_value +
c * weighted_gap),
266 abs(tangential_pressure_value + c_t * tangential_vel *
_dt)) *
267 tangential_pressure_value;
268 const auto term_2 =
_mu *
max(0.0, normal_pressure_value +
c * weighted_gap) *
269 (tangential_pressure_value + c_t * tangential_vel *
_dt);
271 tangential_dof_residual = term_1 - term_2;
276 if (normal_pressure_value.value() <
_epsilon)
278 tangential_dof_residual = tangential_pressure_value;
279 tangential_dof_residual_dir = tangential_pressure_value_dir;
283 const Real epsilon_sqrt = 1.0e-48;
285 const auto lamdba_plus_cg = normal_pressure_value +
c * weighted_gap;
287 std::array<ADReal, 2> lambda_t_plus_ctu;
291 const auto term_1_x =
max(
_mu * lamdba_plus_cg,
292 sqrt(lambda_t_plus_ctu[0] * lambda_t_plus_ctu[0] +
293 lambda_t_plus_ctu[1] * lambda_t_plus_ctu[1] + epsilon_sqrt)) *
294 tangential_pressure_value;
296 const auto term_1_y =
max(
_mu * lamdba_plus_cg,
297 sqrt(lambda_t_plus_ctu[0] * lambda_t_plus_ctu[0] +
298 lambda_t_plus_ctu[1] * lambda_t_plus_ctu[1] + epsilon_sqrt)) *
299 tangential_pressure_value_dir;
301 const auto term_2_x =
_mu *
max(0.0, lamdba_plus_cg) * lambda_t_plus_ctu[0];
303 const auto term_2_y =
_mu *
max(0.0, lamdba_plus_cg) * lambda_t_plus_ctu[1];
305 tangential_dof_residual = term_1_x - term_2_x;
306 tangential_dof_residual_dir = term_1_y - term_2_y;
329 unsigned int component_normal = 0;
334 if (
abs(ny) > threshold_for_Jacobian)
335 component_normal = 1;
336 else if (
abs(nz) > threshold_for_Jacobian)
337 component_normal = 2;
341 std::array<ADReal, 1>{{normal_dof_residual}},
342 std::array<dof_id_type, 1>{{component_normal == 0
344 : (component_normal == 1 ? dof_index_y : dof_index_z)}},
345 component_normal == 0 ? scaling_factor_x
346 : (component_normal == 1 ? scaling_factor_y : scaling_factor_z));
350 std::array<ADReal, 1>{{tangential_dof_residual}},
351 std::array<dof_id_type, 1>{
352 {(component_normal == 0 || component_normal == 2) ? dof_index_y : dof_index_x}},
353 (component_normal == 0 || component_normal == 2) ? scaling_factor_y : scaling_factor_x);
358 std::array<ADReal, 1>{{tangential_dof_residual_dir}},
359 std::array<dof_id_type, 1>{
360 {(component_normal == 0 || component_normal == 1) ? dof_index_z : dof_index_x}},
361 (component_normal == 0 || component_normal == 1) ? scaling_factor_z : scaling_factor_x);
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 mooseError(Args &&... args)
std::map< unsigned int, unsigned int > getPrimaryIpToLowerElementMap(const Elem &primary_elem, const Elem &primary_elem_ip, const Elem &lower_secondary_elem) const
Elem const *const & _lower_primary_elem
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
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)
std::array< MooseUtils::SemidynamicVector< Point, 9 >, 2 > getNodalTangents(const Elem &secondary_elem) const
std::map< unsigned int, unsigned int > getSecondaryIpToLowerElementMap(const Elem &lower_secondary_elem) const
unsigned int number() const
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
void derivInsert(SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< N >> &derivs, libMesh::dof_id_type index, Real value)
const MooseArray< Real > & _coord
processor_id_type processor_id() const
auto min(const L &left, const R &right)