LCOV - code coverage report
Current view: top level - src/auxkernels - MortarFrictionalPressureVectorAux.C (source / functions) Hit Total Coverage
Test: idaholab/moose contact: 8601ad Lines: 41 48 85.4 %
Date: 2025-07-18 13:27:36 Functions: 3 3 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 "MortarFrictionalPressureVectorAux.h"
      11             : #include "SystemBase.h"
      12             : 
      13             : registerMooseObject("ContactApp", MortarFrictionalPressureVectorAux);
      14             : 
      15             : InputParameters
      16         589 : MortarFrictionalPressureVectorAux::validParams()
      17             : {
      18         589 :   InputParameters params = AuxKernel::validParams();
      19         589 :   params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
      20             : 
      21         589 :   params.addClassDescription("This class creates an auxiliary vector for outputting the mortar "
      22             :                              "frictional pressure vector.");
      23        1178 :   params.addRequiredCoupledVar(
      24             :       "tangent_one",
      25             :       "First tangent vector Lagrange's multiplier for computing the mortar "
      26             :       "frictional pressure vector.");
      27        1178 :   params.addRequiredCoupledVar(
      28             :       "tangent_two",
      29             :       "Second tangent vector Lagrange's multiplier for computing the mortar "
      30             :       "frictional pressure vector.");
      31        1178 :   params.addRequiredParam<unsigned int>("component",
      32             :                                         "Cartesian component of frictional tangent vector");
      33             : 
      34        1178 :   params.addRequiredParam<BoundaryName>("primary_boundary",
      35             :                                         "The name of the primary boundary sideset.");
      36        1178 :   params.addRequiredParam<BoundaryName>("secondary_boundary",
      37             :                                         "The name of the secondary boundary sideset.");
      38        1178 :   params.addParam<bool>(
      39        1178 :       "use_displaced_mesh", true, "Whether to use the displaced mesh to get the mortar interface.");
      40         589 :   return params;
      41           0 : }
      42             : 
      43         360 : MortarFrictionalPressureVectorAux::MortarFrictionalPressureVectorAux(const InputParameters & params)
      44             :   : AuxKernel(params),
      45         360 :     _tangent_one(&coupledValueLower("tangent_one")),
      46         360 :     _tangent_two(&coupledValueLower("tangent_two")),
      47         360 :     _fe_problem(*params.get<FEProblemBase *>("_fe_problem_base")),
      48         720 :     _primary_id(_fe_problem.mesh().getBoundaryID(getParam<BoundaryName>("primary_boundary"))),
      49         720 :     _secondary_id(_fe_problem.mesh().getBoundaryID(getParam<BoundaryName>("secondary_boundary"))),
      50         720 :     _component(getParam<unsigned int>("component")),
      51        1080 :     _use_displaced_mesh(getParam<bool>("use_displaced_mesh"))
      52             : {
      53             :   // Only consider nodal quantities
      54         360 :   if (!isNodal())
      55           0 :     mooseError(
      56             :         "MortarFrictionalPressureVector auxiliary kernel can only be used with nodal kernels.");
      57             : 
      58         360 :   if (!_use_displaced_mesh)
      59           0 :     paramError("use_displaced_mesh",
      60             :                "This auxiliary kernel requires the use of displaced meshes to compute the "
      61             :                "frictional pressure vector.");
      62             : 
      63             :   // Kernel need to be boundary restricted
      64         360 :   if (!this->_bnd)
      65           0 :     paramError("boundary",
      66             :                "MortarFrictionalPressureVector auxiliary kernel must be restricted to a boundary.");
      67             : 
      68             :   // Get mortar interfaces
      69             :   const auto & displaced_mortar_interfaces =
      70         360 :       _fe_problem.getMortarInterfaces(/*displaced=*/_use_displaced_mesh);
      71             : 
      72         360 :   if (displaced_mortar_interfaces.size() == 0)
      73           0 :     paramError("tangent_one",
      74             :                "No mortar interface could be identified in this problem. Make sure mortar contact "
      75             :                "is enabled.");
      76             : 
      77         360 :   const auto mortar_dimension = _fe_problem.mesh().dimension() - 1;
      78         360 :   if (mortar_dimension == 1)
      79           0 :     paramError("tangent_two",
      80             :                "MortarFrictionalPressureVector auxiliary kernel can only be used in "
      81             :                "three-dimensional problems");
      82             : 
      83             :   // Get automatic generation object for the boundary pair this auxiliary acts on.
      84         360 :   if (displaced_mortar_interfaces.count(std::make_pair(_primary_id, _secondary_id)) != 1)
      85           0 :     mooseError("primary_boundary",
      86             :                "The boundary pairs do not correspond to a single mortar contact boundary pair. "
      87             :                "Please revise your input file for proper mortar contact constraints and mortar "
      88             :                "frictional pressure vector auxiliary variable definition.");
      89             : 
      90         360 :   _mortar_generation_object =
      91         360 :       &libmesh_map_find(displaced_mortar_interfaces, std::make_pair(_primary_id, _secondary_id));
      92         360 : }
      93             : 
      94             : Real
      95       11295 : MortarFrictionalPressureVectorAux::computeValue()
      96             : {
      97             : 
      98             :   // A node id may correspond to more than one lower-d elements on the secondary surface.
      99             :   // However, we are looping over nodes below, so we will locate the correct geometry
     100             :   const Elem * lower_dimensional_element =
     101       11295 :       libmesh_map_find(_mortar_generation_object->nodesToSecondaryElem(), _current_node->id())[0];
     102             : 
     103             :   // Get nodal tangents for this element
     104             :   const auto & nodal_tangents =
     105       11295 :       _mortar_generation_object->getNodalTangents(*lower_dimensional_element);
     106             : 
     107             :   Real tangent_one_component = 0;
     108             :   Real tangent_two_component = 0;
     109             : 
     110       32295 :   for (const auto lowerd_node : make_range(lower_dimensional_element->n_nodes()))
     111             :   {
     112       32295 :     if (_current_node->id() == lower_dimensional_element->node_id(lowerd_node))
     113             :     {
     114       11295 :       tangent_one_component = nodal_tangents[0][lowerd_node](_component);
     115       11295 :       tangent_two_component = nodal_tangents[1][lowerd_node](_component);
     116       11295 :       break;
     117             :     }
     118             :   }
     119             : 
     120             :   // Compute nodal tangent vector component
     121             :   const Real tangent_vector_component =
     122       11295 :       tangent_one_component * (*_tangent_one)[_qp] + tangent_two_component * (*_tangent_two)[_qp];
     123             : 
     124       11295 :   return tangent_vector_component;
     125             : }

Generated by: LCOV version 1.14