LCOV - code coverage report
Current view: top level - src/constraints - TangentialMortarMechanicalContact.C (source / functions) Hit Total Coverage
Test: idaholab/moose contact: #33390 (250e9c) with base 846a5c Lines: 40 43 93.0 %
Date: 2026-07-31 18:16:12 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          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 : }

Generated by: LCOV version 1.14