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

Generated by: LCOV version 1.14