LCOV - code coverage report
Current view: top level - src/auxkernels - PenetrationAux.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 84 149 56.4 %
Date: 2025-07-17 01:28:37 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             : // MOOSE includes
      11             : #include "PenetrationAux.h"
      12             : #include "PenetrationLocator.h"
      13             : #include "DisplacedProblem.h"
      14             : #include "MooseEnum.h"
      15             : #include "MooseMesh.h"
      16             : 
      17             : #include "libmesh/string_to_enum.h"
      18             : 
      19             : registerMooseObject("MooseApp", PenetrationAux);
      20             : 
      21             : InputParameters
      22       38140 : PenetrationAux::validParams()
      23             : {
      24       38140 :   MooseEnum orders("FIRST SECOND THIRD FOURTH", "FIRST");
      25             : 
      26       38140 :   InputParameters params = AuxKernel::validParams();
      27       38140 :   params.addClassDescription("Auxiliary Kernel for computing several geometry related quantities "
      28             :                              "between two contacting bodies.");
      29             : 
      30       38140 :   params.addRequiredParam<BoundaryName>("paired_boundary", "The boundary to be penetrated");
      31       38140 :   params.addParam<Real>("tangential_tolerance",
      32             :                         "Tangential distance to extend edges of contact surfaces");
      33       38140 :   params.addParam<Real>(
      34             :       "normal_smoothing_distance",
      35             :       "Distance from edge in parametric coordinates over which to smooth contact normal");
      36       38140 :   params.addParam<std::string>("normal_smoothing_method",
      37             :                                "Method to use to smooth normals (edge_based|nodal_normal_based)");
      38       38140 :   params.addParam<MooseEnum>("order", orders, "The finite element order");
      39       38140 :   params.addCoupledVar("secondary_gap_offset", "offset to the gap distance from secondary side");
      40       38140 :   params.addCoupledVar("mapped_primary_gap_offset",
      41             :                        "offset to the gap distance mapped from primary side");
      42             : 
      43       38140 :   params.set<bool>("use_displaced_mesh") = true;
      44             : 
      45             :   // To avoid creating a conversion routine we will list the enumeration options in the same order
      46             :   // as the class-based enum.
      47             :   // Care must be taken to ensure that this list stays in sync with the enum in the .h file.
      48             :   MooseEnum quantity(
      49             :       "distance tangential_distance normal_x normal_y normal_z closest_point_x closest_point_y "
      50             :       "closest_point_z element_id side incremental_slip_magnitude incremental_slip_x "
      51             :       "incremental_slip_y incremental_slip_z accumulated_slip force_x force_y force_z "
      52             :       "normal_force_magnitude normal_force_x normal_force_y normal_force_z "
      53             :       "tangential_force_magnitude "
      54             :       "tangential_force_x tangential_force_y tangential_force_z frictional_energy "
      55             :       "lagrange_multiplier "
      56             :       "mechanical_status",
      57       38140 :       "distance");
      58             : 
      59       38140 :   params.addParam<MooseEnum>(
      60             :       "quantity", quantity, "The quantity to recover from the available penetration information");
      61       76280 :   return params;
      62       38140 : }
      63             : 
      64       12420 : PenetrationAux::PenetrationAux(const InputParameters & parameters)
      65             :   : AuxKernel(parameters),
      66             : 
      67             :     // Here we cast the value of the MOOSE enum to an integer to the class-based enum.
      68       12420 :     _quantity(getParam<MooseEnum>("quantity").getEnum<PenetrationAux::PA_ENUM>()),
      69       12420 :     _penetration_locator(
      70       49569 :         _nodal ? getPenetrationLocator(
      71         962 :                      parameters.get<BoundaryName>("paired_boundary"),
      72       12383 :                      boundaryNames()[0],
      73       12383 :                      Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")))
      74       12457 :                : getQuadraturePenetrationLocator(
      75           3 :                      parameters.get<BoundaryName>("paired_boundary"),
      76          37 :                      boundaryNames()[0],
      77       12457 :                      Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")))),
      78       12420 :     _has_secondary_gap_offset(isCoupled("secondary_gap_offset")),
      79       12420 :     _secondary_gap_offset_var(_has_secondary_gap_offset ? getVar("secondary_gap_offset", 0)
      80             :                                                         : nullptr),
      81       12420 :     _has_mapped_primary_gap_offset(isCoupled("mapped_primary_gap_offset")),
      82       12420 :     _mapped_primary_gap_offset_var(
      83       24840 :         _has_mapped_primary_gap_offset ? getVar("mapped_primary_gap_offset", 0) : nullptr)
      84             : {
      85       12420 :   if (parameters.isParamValid("tangential_tolerance"))
      86         512 :     _penetration_locator.setTangentialTolerance(getParam<Real>("tangential_tolerance"));
      87             : 
      88       12420 :   if (parameters.isParamValid("normal_smoothing_distance"))
      89         304 :     _penetration_locator.setNormalSmoothingDistance(getParam<Real>("normal_smoothing_distance"));
      90             : 
      91       12420 :   if (parameters.isParamValid("normal_smoothing_method"))
      92         104 :     _penetration_locator.setNormalSmoothingMethod(
      93           8 :         parameters.get<std::string>("normal_smoothing_method"));
      94       12420 : }
      95             : 
      96             : Real
      97     8124902 : PenetrationAux::computeValue()
      98             : {
      99     8124902 :   const Node * current_node = nullptr;
     100             : 
     101     8124902 :   if (_nodal)
     102     8116882 :     current_node = _current_node;
     103             :   else
     104        8020 :     current_node = _mesh.getQuadratureNode(_current_elem, _current_side, _qp);
     105             : 
     106     8124902 :   PenetrationInfo * pinfo = _penetration_locator._penetration_info[current_node->id()];
     107             : 
     108             :   // A node that doesn't project has zero force, closest point (i.e. not computed), slip, and its
     109             :   // mechanical status is not in contact.
     110     8124902 :   Real retVal(0);
     111             : 
     112     8124902 :   if (pinfo)
     113     4175219 :     switch (_quantity)
     114             :     {
     115      481141 :       case PA_DISTANCE:
     116      481141 :         retVal =
     117      962282 :             pinfo->_distance -
     118      481141 :             (_has_secondary_gap_offset ? _secondary_gap_offset_var->getNodalValue(*current_node)
     119             :                                        : 0) -
     120      481141 :             (_has_mapped_primary_gap_offset
     121      481141 :                  ? _mapped_primary_gap_offset_var->getNodalValue(*current_node)
     122             :                  : 0);
     123      481141 :         break;
     124      452917 :       case PA_TANG_DISTANCE:
     125      452917 :         retVal = pinfo->_tangential_distance;
     126      452917 :         break;
     127      452826 :       case PA_NORMAL_X:
     128      452826 :         retVal = pinfo->_normal(0);
     129      452826 :         break;
     130      452826 :       case PA_NORMAL_Y:
     131      452826 :         retVal = pinfo->_normal(1);
     132      452826 :         break;
     133      380904 :       case PA_NORMAL_Z:
     134      380904 :         retVal = pinfo->_normal(2);
     135      380904 :         break;
     136      452917 :       case PA_CLOSEST_POINT_X:
     137      452917 :         retVal = pinfo->_closest_point(0);
     138      452917 :         break;
     139      452917 :       case PA_CLOSEST_POINT_Y:
     140      452917 :         retVal = pinfo->_closest_point(1);
     141      452917 :         break;
     142      380995 :       case PA_CLOSEST_POINT_Z:
     143      380995 :         retVal = pinfo->_closest_point(2);
     144      380995 :         break;
     145      214950 :       case PA_ELEM_ID:
     146      214950 :         retVal = static_cast<Real>(pinfo->_elem->id() + 1);
     147      214950 :         break;
     148      452826 :       case PA_SIDE:
     149      452826 :         retVal = static_cast<Real>(pinfo->_side_num);
     150      452826 :         break;
     151           0 :       case PA_INCREMENTAL_SLIP_MAG:
     152           0 :         retVal = pinfo->isCaptured() ? pinfo->_incremental_slip.norm() : 0;
     153           0 :         break;
     154           0 :       case PA_INCREMENTAL_SLIP_X:
     155           0 :         retVal = pinfo->isCaptured() ? pinfo->_incremental_slip(0) : 0;
     156           0 :         break;
     157           0 :       case PA_INCREMENTAL_SLIP_Y:
     158           0 :         retVal = pinfo->isCaptured() ? pinfo->_incremental_slip(1) : 0;
     159           0 :         break;
     160           0 :       case PA_INCREMENTAL_SLIP_Z:
     161           0 :         retVal = pinfo->isCaptured() ? pinfo->_incremental_slip(2) : 0;
     162           0 :         break;
     163           0 :       case PA_ACCUMULATED_SLIP:
     164           0 :         retVal = pinfo->_accumulated_slip;
     165           0 :         break;
     166           0 :       case PA_FORCE_X:
     167           0 :         retVal = pinfo->_contact_force(0);
     168           0 :         break;
     169           0 :       case PA_FORCE_Y:
     170           0 :         retVal = pinfo->_contact_force(1);
     171           0 :         break;
     172           0 :       case PA_FORCE_Z:
     173           0 :         retVal = pinfo->_contact_force(2);
     174           0 :         break;
     175           0 :       case PA_NORMAL_FORCE_MAG:
     176           0 :         retVal = -pinfo->_contact_force * pinfo->_normal;
     177           0 :         break;
     178           0 :       case PA_NORMAL_FORCE_X:
     179           0 :         retVal = (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(0);
     180           0 :         break;
     181           0 :       case PA_NORMAL_FORCE_Y:
     182           0 :         retVal = (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(1);
     183           0 :         break;
     184           0 :       case PA_NORMAL_FORCE_Z:
     185           0 :         retVal = (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(2);
     186           0 :         break;
     187           0 :       case PA_TANGENTIAL_FORCE_MAG:
     188             :       {
     189           0 :         RealVectorValue contact_force_normal((pinfo->_contact_force * pinfo->_normal) *
     190           0 :                                              pinfo->_normal);
     191           0 :         RealVectorValue contact_force_tangential(pinfo->_contact_force - contact_force_normal);
     192           0 :         retVal = contact_force_tangential.norm();
     193           0 :         break;
     194             :       }
     195           0 :       case PA_TANGENTIAL_FORCE_X:
     196           0 :         retVal =
     197           0 :             pinfo->_contact_force(0) - (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(0);
     198           0 :         break;
     199           0 :       case PA_TANGENTIAL_FORCE_Y:
     200           0 :         retVal =
     201           0 :             pinfo->_contact_force(1) - (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(1);
     202           0 :         break;
     203           0 :       case PA_TANGENTIAL_FORCE_Z:
     204           0 :         retVal =
     205           0 :             pinfo->_contact_force(2) - (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(2);
     206           0 :         break;
     207           0 :       case PA_FRICTIONAL_ENERGY:
     208           0 :         retVal = pinfo->_frictional_energy;
     209           0 :         break;
     210           0 :       case PA_LAGRANGE_MULTIPLIER:
     211           0 :         retVal = pinfo->_lagrange_multiplier;
     212           0 :         break;
     213           0 :       case PA_MECH_STATUS:
     214           0 :         retVal = pinfo->_mech_status;
     215           0 :         break;
     216           0 :       default:
     217           0 :         mooseError("Unknown penetration info quantity in auxiliary kernel.");
     218             :     } // switch
     219             : 
     220     8124902 :   return retVal;
     221             : }

Generated by: LCOV version 1.14