LCOV - code coverage report
Current view: top level - src/auxkernels - MortarArchardsLawAux.C (source / functions) Hit Total Coverage
Test: idaholab/moose contact: 8601ad Lines: 52 55 94.5 %
Date: 2025-07-18 13:27:36 Functions: 5 5 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 "MortarArchardsLawAux.h"
      11             : #include "MooseVariableFE.h"
      12             : #include "FEProblemBase.h"
      13             : #include "Assembly.h"
      14             : 
      15             : registerMooseObject("ContactApp", MortarArchardsLawAux);
      16             : 
      17             : InputParameters
      18         107 : MortarArchardsLawAux::validParams()
      19             : {
      20         107 :   InputParameters params = MortarNodalAuxKernel::validParams();
      21         107 :   params.addClassDescription(
      22             :       "Returns the weighted gap velocity at a node. This quantity is useful for mortar contact, "
      23             :       "particularly when dual basis functions are used in contact mechanics");
      24         214 :   params.addCoupledVar("v",
      25             :                        "Optional variable to take the value of. If omitted the value of the "
      26             :                        "`variable` itself is returned.");
      27         214 :   params.addRequiredCoupledVar("displacements",
      28             :                                "The displacement variables. This mortar nodal auxiliary kernel can "
      29             :                                "take two or three displacements");
      30         214 :   params.addRequiredCoupledVar("normal_pressure",
      31             :                                "The name of the Lagrange multiplier that holds the normal contact "
      32             :                                "pressure in mortar formulations");
      33         214 :   params.addParam<bool>("use_displaced_mesh",
      34         214 :                         true,
      35             :                         "Whether to use the displaced mesh to compute the auxiliary kernel value");
      36         214 :   params.addParam<bool>(
      37             :       "incremental",
      38         214 :       true,
      39             :       "Whether to accumulate worn-out depth (The default 'true' is strongly recommended)");
      40         214 :   params.addRequiredParam<Real>(
      41             :       "friction_coefficient",
      42             :       "Friction coefficient used to compute wear (to match that of frictional contact)");
      43         214 :   params.addRequiredParam<Real>(
      44             :       "energy_wear_coefficient",
      45             :       "Energy wear coefficient is a surface-dependent parameter used in Archard's wear law");
      46         107 :   params.set<bool>("interpolate_normals") = false;
      47             : 
      48         107 :   return params;
      49           0 : }
      50             : 
      51          62 : MortarArchardsLawAux::MortarArchardsLawAux(const InputParameters & parameters)
      52             :   : MortarNodalAuxKernel(parameters),
      53          62 :     _normal_pressure(coupledValueLower("normal_pressure")),
      54         124 :     _friction_coefficient(getParam<Real>("friction_coefficient")),
      55         124 :     _energy_wear_coefficient(getParam<Real>("energy_wear_coefficient")),
      56          62 :     _displacements(
      57         124 :         {getVar("displacements", 0), getVar("displacements", 1), getVar("displacements", 2)}),
      58          62 :     _has_disp_z(_displacements[2] ? true : false),
      59          62 :     _secondary_x_dot(_displacements[0]->adUDot()),
      60          62 :     _primary_x_dot(_displacements[0]->adUDotNeighbor()),
      61          62 :     _secondary_y_dot(_displacements[1]->adUDot()),
      62          62 :     _primary_y_dot(_displacements[1]->adUDotNeighbor()),
      63          62 :     _secondary_z_dot(_has_disp_z ? &_displacements[2]->adUDot() : nullptr),
      64          62 :     _primary_z_dot(_has_disp_z ? &_displacements[2]->adUDotNeighbor() : nullptr),
      65          62 :     _worn_depth(0),
      66          62 :     _qp_gap_velocity_nodal(0)
      67             : {
      68          62 :   if (!_displaced)
      69           0 :     paramError("use_displaced_mesh",
      70             :                "The MortarArchardsLawAux auxiliary kernel requires the use of displaced meshes to "
      71             :                "compute the worn-out depth.");
      72          62 : }
      73             : 
      74             : Real
      75       37800 : MortarArchardsLawAux::computeValue()
      76             : {
      77             :   mooseAssert(_normals.size() == _test_lower.size(),
      78             :               "Normals and test_lower must be the same size");
      79       37800 :   _worn_depth = 0;
      80      113400 :   for (_qp = 0; _qp < _qrule_msm->n_points(); _qp++)
      81             :   {
      82       75600 :     computeQpProperties();
      83      226800 :     for (_i = 0; _i < _test_lower.size(); ++_i)
      84      151200 :       computeQpIProperties();
      85             :   }
      86             : 
      87       37800 :   return _worn_depth;
      88             : }
      89             : 
      90             : void
      91       75600 : MortarArchardsLawAux::computeQpProperties()
      92             : {
      93       75600 :   _msm_volume += _JxW_msm[_qp] * _coord_msm[_qp];
      94       75600 : }
      95             : 
      96             : void
      97      151200 : MortarArchardsLawAux::computeQpIProperties()
      98             : {
      99             :   RealVectorValue gap_velocity_vec;
     100      302400 :   gap_velocity_vec(0) = MetaPhysicL::raw_value(_secondary_x_dot[_qp] - _primary_x_dot[_qp]);
     101      302400 :   gap_velocity_vec(1) = MetaPhysicL::raw_value(_secondary_y_dot[_qp] - _primary_y_dot[_qp]);
     102             : 
     103      151200 :   if (_has_disp_z)
     104           0 :     gap_velocity_vec(2) = MetaPhysicL::raw_value((*_secondary_z_dot)[_qp] - (*_primary_z_dot)[_qp]);
     105             : 
     106             :   // Remove point-wise normal component of the relative velocity
     107      151200 :   gap_velocity_vec -= gap_velocity_vec.contract(_normals[_i]) * _normals[_i];
     108             : 
     109             :   // Compute norm of the relative tangential velocity (used to compute the weighted quantity)
     110      151200 :   const auto norm_tangential_vel = gap_velocity_vec.norm();
     111             : 
     112      151200 :   const auto worn_out_depth_dt = norm_tangential_vel * _energy_wear_coefficient *
     113      151200 :                                  _friction_coefficient * _normal_pressure[0] * _dt * _JxW_msm[_qp] *
     114      151200 :                                  _coord_msm[_qp];
     115             : 
     116             :   // Accumulate worn-out depth over time.
     117      151200 :   _worn_depth += _test_lower[_i][_qp] * worn_out_depth_dt;
     118      151200 : }

Generated by: LCOV version 1.14