Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "TangentialMortarMechanicalContact.h" 11 : #include "WeightedVelocitiesUserObject.h" 12 : #include "AutomaticMortarGeneration.h" 13 : 14 : registerMooseObject("ContactApp", TangentialMortarMechanicalContact); 15 : 16 : InputParameters 17 1775 : TangentialMortarMechanicalContact::validParams() 18 : { 19 1775 : InputParameters params = ADMortarLagrangeConstraint::validParams(); 20 : 21 3550 : MooseEnum component("x=0 y=1 z=2"); 22 3550 : params.addRequiredParam<MooseEnum>( 23 : "component", component, "The force component constraint that this object is supplying"); 24 : 25 : // This enum is used to pick the proper 'tangent' vector (i.e. tangent or binormal) 26 3550 : MooseEnum direction("direction_1 direction_2", "direction_1"); 27 3550 : params.addParam<MooseEnum>("direction", 28 : direction, 29 : "Tangent direction to compute the residual due to frictional contact"); 30 1775 : params.addClassDescription( 31 : "Used to apply tangential stresses from frictional contact using lagrange multipliers"); 32 3550 : params.addRequiredParam<UserObjectName>("weighted_velocities_uo", 33 : "The weighted velocities user object."); 34 1775 : params.set<bool>("interpolate_normals") = false; 35 1775 : params.set<bool>("compute_lm_residual") = false; 36 1775 : return params; 37 1775 : } 38 : 39 986 : TangentialMortarMechanicalContact::TangentialMortarMechanicalContact( 40 986 : const InputParameters & parameters) 41 : : ADMortarLagrangeConstraint(parameters), 42 986 : _component(getParam<MooseEnum>("component")), 43 1972 : _direction(getParam<MooseEnum>("direction")), 44 1972 : _weighted_velocities_uo(getUserObject<WeightedVelocitiesUserObject>("weighted_velocities_uo")) 45 : { 46 1972 : if (getParam<bool>("interpolate_normals")) 47 0 : paramError("interpolate_normals", 48 : "Mechanical mortar contact uses tangents derived from normalized secondary nodal " 49 : "normals and cannot be combined with quadrature-point normal interpolation."); 50 986 : } 51 : 52 : ADReal 53 134211024 : TangentialMortarMechanicalContact::computeQpResidual(Moose::MortarType type) 54 : { 55 134211024 : const auto tangent_component = [this](const unsigned int geometry_index) 56 : { 57 134211024 : if (_weighted_velocities_uo.usesNodalNormalDerivatives()) 58 : { 59 : const auto tangents = 60 29071568 : _weighted_velocities_uo.contactTangents(*_lower_secondary_elem, geometry_index); 61 58143136 : return tangents[_direction](_component) / tangents[_direction].norm(); 62 : } 63 : 64 105139456 : const auto & tangents = amg().getNodalTangents(*_lower_secondary_elem); 65 210278912 : return ADReal(tangents[_direction][geometry_index](_component) / 66 105139456 : tangents[_direction][geometry_index].norm()); 67 134211024 : }; 68 : 69 268422048 : MooseEnum direction("direction_1 direction_2", "direction_1"); 70 : 71 : const auto tangential_pressure = 72 134211024 : _direction.compareCurrent(direction) 73 69656976 : ? _weighted_velocities_uo.contactTangentialPressureDirOne()[_qp] 74 203868000 : : _weighted_velocities_uo.contactTangentialPressureDirTwo()[_qp]; 75 : 76 134211024 : switch (type) 77 : { 78 67105512 : case Moose::MortarType::Secondary: 79 : // We have taken the convention the lagrange multiplier must have the same sign as the 80 : // relative slip velocity of the secondary face. So positive lambda indicates that force is 81 : // being applied in the negative direction, so we want to decrease the momentum in the system, 82 : // which means we want an outflow of momentum, which means we want the residual to be positive 83 : // in that case. Negative lambda means force is being applied in the positive direction, so we 84 : // want to increase momentum in the system, which means we want an inflow of momentum, which 85 : // means we want the residual to be negative in that case. So the sign of this residual should 86 : // be the same as the sign of lambda 87 : { 88 67105512 : const auto geometry_index = libmesh_map_find(_secondary_ip_lowerd_map, _i); 89 134211024 : return _test_secondary[_i][_qp] * tangential_pressure * tangent_component(geometry_index); 90 : } 91 67105512 : case Moose::MortarType::Primary: 92 : { 93 67105512 : const auto geometry_index = libmesh_map_find(_primary_ip_lowerd_map, _i); 94 134211024 : return -_test_primary[_i][_qp] * tangential_pressure * tangent_component(geometry_index); 95 : } 96 0 : default: 97 0 : return 0; 98 : } 99 134211024 : }