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

Generated by: LCOV version 1.14