LCOV - code coverage report
Current view: top level - src/auxkernels - MortarNodalAuxKernel.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 57 64 89.1 %
Date: 2026-05-29 20:35:17 Functions: 6 13 46.2 %
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 "MortarNodalAuxKernel.h"
      11             : #include "MooseVariableField.h"
      12             : #include "MortarUtils.h"
      13             : #include "MooseUtils.h"
      14             : #include "AutomaticMortarGeneration.h"
      15             : #include "libmesh/quadrature.h"
      16             : 
      17             : namespace
      18             : {
      19             : const InputParameters &
      20          78 : setBoundaryParam(const InputParameters & params_in)
      21             : {
      22          78 :   InputParameters & ret = const_cast<InputParameters &>(params_in);
      23         156 :   ret.set<std::vector<BoundaryName>>("boundary") = {
      24         234 :       params_in.get<BoundaryName>("secondary_boundary")};
      25          78 :   return ret;
      26         156 : }
      27             : }
      28             : 
      29             : template <typename ComputeValueType>
      30             : InputParameters
      31        3211 : MortarNodalAuxKernelTempl<ComputeValueType>::validParams()
      32             : {
      33        3211 :   InputParameters params = AuxKernelTempl<ComputeValueType>::validParams();
      34        3211 :   params += MortarConsumerInterface::validParams();
      35        6422 :   params.set<bool>("ghost_point_neighbors") = true;
      36        6422 :   params.suppressParameter<std::vector<BoundaryName>>("boundary");
      37        6422 :   params.suppressParameter<std::vector<SubdomainName>>("block");
      38        6422 :   params.addParam<bool>(
      39        6422 :       "incremental", false, "Whether to accumulate mortar auxiliary kernel value");
      40             : 
      41             :   // We should probably default use_displaced_mesh to true. If no displaced mesh exists
      42             :   // FEProblemBase::addKernel will automatically correct it to false. However,
      43             :   // this will still prompt a call from AugmentSparsityOnInterface to get a displaced
      44             :   // mortar interface since object._use_displaced_mesh = true.
      45             : 
      46        3211 :   return params;
      47           0 : }
      48             : 
      49             : template <typename ComputeValueType>
      50          78 : MortarNodalAuxKernelTempl<ComputeValueType>::MortarNodalAuxKernelTempl(
      51             :     const InputParameters & parameters)
      52             :   : AuxKernelTempl<ComputeValueType>(setBoundaryParam(parameters)),
      53             :     MortarConsumerInterface(this),
      54          78 :     _displaced(this->template getParam<bool>("use_displaced_mesh")),
      55         312 :     _fe_problem(*this->template getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
      56          78 :     _msm_volume(0),
      57         156 :     _incremental(this->template getParam<bool>("incremental")),
      58          78 :     _u_old(uOld()),
      59          78 :     _test_lower(_var.phiLower()),
      60         156 :     _coord_msm(_assembly.mortarCoordTransformation())
      61             : {
      62          78 :   if (!isNodal())
      63           0 :     paramError("variable",
      64             :                "MortarNodalAuxKernel derived classes populate nodal aux variables only.");
      65          78 : }
      66             : 
      67             : template <typename ComputeValueType>
      68             : void
      69          78 : MortarNodalAuxKernelTempl<ComputeValueType>::initialSetup()
      70             : {
      71          78 :   AuxKernelTempl<ComputeValueType>::initialSetup();
      72             : 
      73          78 :   std::array<const MortarNodalAuxKernelTempl<ComputeValueType> *, 1> consumers = {{this}};
      74             : 
      75          78 :   Moose::Mortar::setupMortarMaterials(consumers,
      76             :                                       _fe_problem,
      77             :                                       amg(),
      78          78 :                                       _tid,
      79          78 :                                       _secondary_ip_sub_to_mats,
      80          78 :                                       _primary_ip_sub_to_mats,
      81          78 :                                       _secondary_boundary_mats);
      82          78 : }
      83             : 
      84             : template <typename ComputeValueType>
      85             : void
      86         682 : MortarNodalAuxKernelTempl<ComputeValueType>::compute()
      87             : {
      88         682 :   if (!_var.isNodalDefined())
      89          87 :     return;
      90             : 
      91         595 :   ComputeValueType value(0);
      92         595 :   Real total_volume = 0;
      93             : 
      94         595 :   const auto & its = amg().secondariesToMortarSegments(*_current_node);
      95             : 
      96        2859 :   auto act_functor = [&value, &total_volume, this]()
      97             :   {
      98        1132 :     _msm_volume = 0;
      99        1132 :     setNormals();
     100        1132 :     value += computeValue();
     101           0 :     total_volume += _msm_volume;
     102             :   };
     103             : 
     104         595 :   std::array<MortarNodalAuxKernelTempl<ComputeValueType> *, 1> consumers = {{this}};
     105             : 
     106         595 :   Moose::Mortar::loopOverMortarSegments(its,
     107             :                                         _assembly,
     108             :                                         _subproblem,
     109             :                                         _fe_problem,
     110             :                                         amg(),
     111         595 :                                         _displaced,
     112             :                                         consumers,
     113         595 :                                         _tid,
     114         595 :                                         _secondary_ip_sub_to_mats,
     115         595 :                                         _primary_ip_sub_to_mats,
     116         595 :                                         _secondary_boundary_mats,
     117             :                                         act_functor,
     118             :                                         /*reinit_mortar_user_objects=*/false);
     119             : 
     120             :   // We have to reinit the node for this variable in order to get the dof index set for the node
     121         595 :   _var.reinitNode();
     122             : 
     123             :   // If the node doesn't have corresponding mortar segments, force the value assigned in this step
     124             :   // to be zero. This can be useful when nodes initially do not project but will project at a
     125             :   // different stage of the simulation
     126             : 
     127         595 :   if (MooseUtils::relativeFuzzyEqual(total_volume, 0.0))
     128           0 :     value = 0;
     129             :   else
     130         595 :     value /= total_volume;
     131             : 
     132             :   // Allow mortar auxiliary kernels to compute quantities incrementally
     133         595 :   if (!_incremental)
     134         595 :     _var.setNodalValue(value);
     135             :   else
     136             :   {
     137             :     mooseAssert(_u_old.size() == 1,
     138             :                 "Expected 1 value in MortarNodalAuxKernel, but got " << _u_old.size());
     139           0 :     _var.setNodalValue(value + _u_old[0]);
     140             :   }
     141         595 : }
     142             : 
     143             : template <typename ComputeValueType>
     144             : void
     145           0 : MortarNodalAuxKernelTempl<ComputeValueType>::precalculateValue()
     146             : {
     147           0 :   mooseError(
     148             :       "not clear where this should be implemented in the compute loop. If you want to implement "
     149             :       "this function, please contact a MOOSE developer and tell them your use case");
     150             : }
     151             : 
     152             : // Explicitly instantiates the two versions of the MortarNodalAuxKernelTempl class
     153             : template class MortarNodalAuxKernelTempl<Real>;
     154             : template class MortarNodalAuxKernelTempl<RealVectorValue>;

Generated by: LCOV version 1.14