LCOV - code coverage report
Current view: top level - src/userobjects - WeightedVelocitiesUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose contact: #33390 (250e9c) with base 846a5c Lines: 72 75 96.0 %
Date: 2026-07-31 18:16:12 Functions: 8 9 88.9 %
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 "WeightedVelocitiesUserObject.h"
      11             : #include "MooseVariableField.h"
      12             : #include "SubProblem.h"
      13             : #include "SystemBase.h"
      14             : #include "MortarUtils.h"
      15             : #include "MooseUtils.h"
      16             : #include "MortarContactUtils.h"
      17             : #include "AutomaticMortarGeneration.h"
      18             : #include "libmesh/quadrature.h"
      19             : 
      20             : InputParameters
      21         722 : WeightedVelocitiesUserObject::validParams()
      22             : {
      23         722 :   InputParameters params = WeightedGapUserObject::validParams();
      24        1444 :   params.addRequiredParam<VariableName>("secondary_variable",
      25             :                                         "Primal variable on secondary surface.");
      26        1444 :   params.addParam<VariableName>(
      27             :       "primary_variable",
      28             :       "Primal variable on primary surface. If this parameter is not provided then the primary "
      29             :       "variable will be initialized to the secondary variable");
      30         722 :   return params;
      31           0 : }
      32             : 
      33         361 : WeightedVelocitiesUserObject::WeightedVelocitiesUserObject(const InputParameters & parameters)
      34             :   : WeightedGapUserObject(parameters),
      35         722 :     _sys(*getCheckedPointerParam<SystemBase *>("_sys")),
      36         361 :     _secondary_var(
      37         361 :         isParamValid("secondary_variable")
      38        1083 :             ? _sys.getActualFieldVariable<Real>(_tid, parameters.getMooseType("secondary_variable"))
      39         361 :             : _sys.getActualFieldVariable<Real>(_tid, parameters.getMooseType("primary_variable"))),
      40         361 :     _primary_var(
      41         361 :         isParamValid("primary_variable")
      42         361 :             ? _sys.getActualFieldVariable<Real>(_tid, parameters.getMooseType("primary_variable"))
      43             :             : _secondary_var),
      44         361 :     _secondary_x_dot(_secondary_var.adUDot()),
      45         361 :     _primary_x_dot(_primary_var.adUDotNeighbor()),
      46         361 :     _secondary_y_dot(adCoupledDot("disp_y")),
      47         361 :     _primary_y_dot(adCoupledNeighborValueDot("disp_y")),
      48         361 :     _secondary_z_dot(_has_disp_z ? &adCoupledDot("disp_z") : nullptr),
      49         361 :     _primary_z_dot(_has_disp_z ? &adCoupledNeighborValueDot("disp_z") : nullptr),
      50         361 :     _3d(_has_disp_z)
      51             : {
      52         722 :   if (!getParam<bool>("use_displaced_mesh"))
      53           0 :     paramError("use_displaced_mesh",
      54             :                "'use_displaced_mesh' must be true for the WeightedVelocitiesUserObject object");
      55         361 : }
      56             : 
      57             : std::array<ADRealVectorValue, 2>
      58    31600644 : WeightedVelocitiesUserObject::contactTangents(const Elem & lower_secondary_elem,
      59             :                                               const unsigned int nodal_index) const
      60             : {
      61             :   mooseAssert(nodal_index < lower_secondary_elem.n_nodes(),
      62             :               "Nodal tangent index must refer to a node on the secondary element.");
      63             :   mooseAssert(usesNodalNormalDerivatives(),
      64             :               "AD contact tangents should only be requested while recording nodal-normal "
      65             :               "derivatives.");
      66    31600644 :   return Moose::Mortar::householderTangents(contactNormal(lower_secondary_elem, nodal_index));
      67             : }
      68             : 
      69             : void
      70     2928562 : WeightedVelocitiesUserObject::computeQpProperties()
      71             : {
      72             :   // Compute the value of _qp_gap
      73     2928562 :   WeightedGapUserObject::computeQpProperties();
      74             : 
      75             :   // Trim derivatives
      76     2928562 :   const auto & primary_ip_lowerd_map = amg().getPrimaryIpToLowerElementMap(
      77     2928562 :       *_lower_primary_elem, *_lower_primary_elem->interior_parent(), *_lower_secondary_elem);
      78             :   const auto & secondary_ip_lowerd_map =
      79     2928562 :       amg().getSecondaryIpToLowerElementMap(*_lower_secondary_elem);
      80             : 
      81     2928562 :   std::array<const MooseVariable *, 3> var_array{{_disp_x_var, _disp_y_var, _disp_z_var}};
      82             :   std::array<ADReal, 3> primary_disp_dot{
      83     2928562 :       {_primary_x_dot[_qp], _primary_y_dot[_qp], _has_disp_z ? (*_primary_z_dot)[_qp] : 0}};
      84             :   std::array<ADReal, 3> secondary_disp_dot{
      85     2928562 :       {_secondary_x_dot[_qp], _secondary_y_dot[_qp], _has_disp_z ? (*_secondary_z_dot)[_qp] : 0}};
      86             : 
      87     2928562 :   trimInteriorNodeDerivatives(primary_ip_lowerd_map, var_array, primary_disp_dot, false);
      88     2928562 :   trimInteriorNodeDerivatives(secondary_ip_lowerd_map, var_array, secondary_disp_dot, true);
      89             : 
      90             :   const ADReal & prim_x_dot = primary_disp_dot[0];
      91             :   const ADReal & prim_y_dot = primary_disp_dot[1];
      92             :   const ADReal * prim_z_dot = nullptr;
      93     2928562 :   if (_has_disp_z)
      94             :     prim_z_dot = &primary_disp_dot[2];
      95             : 
      96             :   const ADReal & sec_x_dot = secondary_disp_dot[0];
      97             :   const ADReal & sec_y_dot = secondary_disp_dot[1];
      98             :   const ADReal * sec_z_dot = nullptr;
      99     2928562 :   if (_has_disp_z)
     100             :     sec_z_dot = &secondary_disp_dot[2];
     101             : 
     102             :   // Build relative velocity vector
     103             :   ADRealVectorValue relative_velocity;
     104             : 
     105     2928562 :   if (_3d)
     106     2267792 :     relative_velocity = {sec_x_dot - prim_x_dot, sec_y_dot - prim_y_dot, *sec_z_dot - *prim_z_dot};
     107             :   else
     108     1321540 :     relative_velocity = {sec_x_dot - prim_x_dot, sec_y_dot - prim_y_dot, 0.0};
     109             : 
     110             :   // Geometry is averaged and used at the nodes for constraint enforcement.
     111             :   _qp_real_tangential_velocity_nodal = relative_velocity;
     112     5857124 :   _qp_tangential_velocity_nodal = relative_velocity * (_JxW_msm[_qp] * _coord[_qp]);
     113     2928562 : }
     114             : 
     115             : void
     116    10392708 : WeightedVelocitiesUserObject::computeQpIProperties()
     117             : {
     118    10392708 :   WeightedGapUserObject::computeQpIProperties();
     119             : 
     120             :   // Get the _dof_to_weighted_tangential_velocity map
     121             :   const DofObject * const dof =
     122    10392708 :       _is_weighted_gap_nodal ? static_cast<const DofObject *>(_lower_secondary_elem->node_ptr(_i))
     123           0 :                              : static_cast<const DofObject *>(_lower_secondary_elem);
     124             : 
     125    10392708 :   if (usesNodalNormalDerivatives())
     126             :   {
     127     2529076 :     const auto tangents = contactTangents(*_lower_secondary_elem, _i);
     128     7587228 :     for (const auto direction : make_range(_3d ? 2 : 1))
     129             :     {
     130             :       _dof_to_weighted_tangential_velocity[dof][direction] +=
     131     9796968 :           (*_test)[_i][_qp] * _qp_tangential_velocity_nodal * tangents[direction];
     132             :       _dof_to_real_tangential_velocity[dof][direction] +=
     133     9796968 :           (*_test)[_i][_qp] * _qp_real_tangential_velocity_nodal * tangents[direction];
     134             :     }
     135             :   }
     136             :   else
     137             :   {
     138     7863632 :     const auto & nodal_tangents = amg().getNodalTangents(*_lower_secondary_elem);
     139             : 
     140             :     _dof_to_weighted_tangential_velocity[dof][0] +=
     141    15727264 :         (*_test)[_i][_qp] * _qp_tangential_velocity_nodal * nodal_tangents[0][_i];
     142             :     _dof_to_real_tangential_velocity[dof][0] +=
     143    15727264 :         (*_test)[_i][_qp] * _qp_real_tangential_velocity_nodal * nodal_tangents[0][_i];
     144             : 
     145             :     // Get the _dof_to_weighted_tangential_velocity map for a second direction
     146     7863632 :     if (_3d)
     147             :     {
     148             :       _dof_to_weighted_tangential_velocity[dof][1] +=
     149    13403520 :           (*_test)[_i][_qp] * _qp_tangential_velocity_nodal * nodal_tangents[1][_i];
     150             : 
     151             :       _dof_to_real_tangential_velocity[dof][1] +=
     152    13403520 :           (*_test)[_i][_qp] * _qp_real_tangential_velocity_nodal * nodal_tangents[1][_i];
     153             :     }
     154             :   }
     155    10392708 : }
     156             : 
     157             : void
     158       65856 : WeightedVelocitiesUserObject::selfInitialize()
     159             : {
     160             :   _dof_to_weighted_tangential_velocity.clear();
     161             :   _dof_to_real_tangential_velocity.clear();
     162       65856 : }
     163             : 
     164             : void
     165       50898 : WeightedVelocitiesUserObject::initialize()
     166             : {
     167             :   // Clear weighted gaps
     168       50898 :   WeightedGapUserObject::initialize();
     169       50898 :   selfInitialize();
     170       50898 : }
     171             : 
     172             : void
     173       65856 : WeightedVelocitiesUserObject::finalize()
     174             : {
     175       65856 :   WeightedGapUserObject::finalize();
     176             : 
     177             :   // If the constraint is performed by the owner, then we don't need any data sent back; the owner
     178             :   // will take care of it. But if the constraint is not performed by the owner and we might have to
     179             :   // do some of the constraining ourselves, then we need data sent back to us
     180       65856 :   const bool send_data_back = !constrainedByOwner();
     181             : 
     182       65856 :   Moose::Mortar::Contact::communicateVelocities(_dof_to_weighted_tangential_velocity,
     183       65856 :                                                 _subproblem.mesh(),
     184       65856 :                                                 _nodal,
     185             :                                                 _communicator,
     186             :                                                 send_data_back);
     187      131712 :   Moose::Mortar::Contact::communicateVelocities(
     188       65856 :       _dof_to_real_tangential_velocity, _subproblem.mesh(), _nodal, _communicator, send_data_back);
     189       65856 : }

Generated by: LCOV version 1.14