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 "NormalMortarMechanicalContact.h" 11 : #include "WeightedGapUserObject.h" 12 : 13 : registerMooseObject("ContactApp", NormalMortarMechanicalContact); 14 : 15 : InputParameters 16 3530 : NormalMortarMechanicalContact::validParams() 17 : { 18 3530 : InputParameters params = ADMortarLagrangeConstraint::validParams(); 19 : 20 7060 : MooseEnum component("x=0 y=1 z=2"); 21 7060 : params.addRequiredParam<MooseEnum>( 22 : "component", component, "The force component constraint that this object is supplying"); 23 3530 : params.addClassDescription( 24 : "This class is used to apply normal contact forces using lagrange multipliers"); 25 3530 : params.set<bool>("compute_lm_residual") = false; 26 3530 : params.set<bool>("interpolate_normals") = false; 27 7060 : params.addRequiredParam<UserObjectName>("weighted_gap_uo", "The weighted gap user object."); 28 3530 : return params; 29 3530 : } 30 : 31 2008 : NormalMortarMechanicalContact::NormalMortarMechanicalContact(const InputParameters & parameters) 32 : : ADMortarLagrangeConstraint(parameters), 33 2008 : _component(getParam<MooseEnum>("component")), 34 4016 : _weighted_gap_uo(getUserObject<WeightedGapUserObject>("weighted_gap_uo")) 35 : { 36 4016 : if (getParam<bool>("interpolate_normals")) 37 0 : paramError("interpolate_normals", 38 : "Mechanical mortar contact uses normalized secondary nodal normals and cannot be " 39 : "combined with quadrature-point normal interpolation."); 40 2008 : } 41 : 42 : ADReal 43 211644036 : NormalMortarMechanicalContact::computeQpResidual(Moose::MortarType type) 44 : { 45 211644036 : switch (type) 46 : { 47 105797578 : case Moose::MortarType::Secondary: 48 : // If normals is positive, then this residual is positive, indicating that we have an outflow 49 : // of momentum, which in turn indicates that the momentum will tend to decrease at this 50 : // location with time, which is what we want because the force vector is in the negative 51 : // direction (always opposite of the normals). Conversely, if the normals is negative, then 52 : // this residual is negative, indicating that we have an inflow of momentum, which in turn 53 : // indicates the momentum will tend to increase at this location with time, which is what we 54 : // want because the force vector is in the positive direction (always opposite of the 55 : // normals). 56 : // Get the _dof_to_weighted_gap map 57 : { 58 105797578 : const auto normal_index = libmesh_map_find(_secondary_ip_lowerd_map, _i); 59 : const auto normal = 60 105797578 : _weighted_gap_uo.usesNodalNormalDerivatives() 61 105797578 : ? _weighted_gap_uo.contactNormal(*_lower_secondary_elem, normal_index) 62 87537300 : : ADRealVectorValue(_normals[normal_index]); 63 211595156 : return _test_secondary[_i][_qp] * _weighted_gap_uo.contactPressure()[_qp] * 64 105797578 : normal(_component); 65 : } 66 : 67 105797578 : case Moose::MortarType::Primary: 68 : // The normal vector is signed according to the secondary face, so we need to introduce a 69 : // negative sign here 70 : { 71 105797578 : const auto normal_index = libmesh_map_find(_primary_ip_lowerd_map, _i); 72 : const auto normal = 73 105797578 : _weighted_gap_uo.usesNodalNormalDerivatives() 74 105797578 : ? _weighted_gap_uo.contactNormal(*_lower_secondary_elem, normal_index) 75 87537300 : : ADRealVectorValue(_normals[normal_index]); 76 211595156 : return -_test_primary[_i][_qp] * _weighted_gap_uo.contactPressure()[_qp] * 77 105797578 : normal(_component); 78 : } 79 48880 : default: 80 48880 : return 0; 81 : } 82 : }