LCOV - code coverage report
Current view: top level - src/fvkernels - PINSFVMomentumDiffusion.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: ba1ead Lines: 46 48 95.8 %
Date: 2025-08-13 06:50:25 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             : #include "PINSFVMomentumDiffusion.h"
      11             : #include "PINSFVSuperficialVelocityVariable.h"
      12             : #include "NS.h"
      13             : #include "INSFVRhieChowInterpolator.h"
      14             : #include "SystemBase.h"
      15             : 
      16             : registerMooseObject("NavierStokesApp", PINSFVMomentumDiffusion);
      17             : 
      18             : InputParameters
      19        9858 : PINSFVMomentumDiffusion::validParams()
      20             : {
      21        9858 :   auto params = INSFVMomentumDiffusion::validParams();
      22        9858 :   params.addClassDescription(
      23             :       "Viscous diffusion term, div(mu eps grad(u_d / eps)), in the porous media "
      24             :       "incompressible Navier-Stokes momentum equation.");
      25        9858 :   params.addRequiredParam<MooseFunctorName>(NS::porosity, "Porosity auxiliary variable");
      26        9858 :   return params;
      27           0 : }
      28             : 
      29        5575 : PINSFVMomentumDiffusion::PINSFVMomentumDiffusion(const InputParameters & params)
      30        5575 :   : INSFVMomentumDiffusion(params), _eps(getFunctor<ADReal>(NS::porosity))
      31             : {
      32        5575 :   if (!dynamic_cast<PINSFVSuperficialVelocityVariable *>(&_var))
      33           0 :     mooseError("PINSFVMomentumDiffusion may only be used with a superficial velocity "
      34             :                "variable, of variable type PINSFVSuperficialVelocityVariable.");
      35        5575 : }
      36             : 
      37             : ADReal
      38    39953472 : PINSFVMomentumDiffusion::computeStrongResidual(const bool populate_a_coeffs)
      39             : {
      40             :   using namespace Moose::FV;
      41             : 
      42    39953472 :   const bool has_elem = (_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
      43    39953472 :                          _face_type == FaceInfo::VarFaceNeighbors::BOTH);
      44    39953472 :   const bool has_neighbor = (_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR ||
      45    39953472 :                              _face_type == FaceInfo::VarFaceNeighbors::BOTH);
      46             : 
      47    39953472 :   const auto elem_face = elemArg();
      48    39953472 :   const auto neighbor_face = neighborArg();
      49    39953472 :   const auto state = determineState();
      50             : 
      51             :   // Compute the diffusion driven by the velocity gradient
      52             :   // Interpolate viscosity divided by porosity on the face
      53             :   ADReal mu_face;
      54             : 
      55    39953472 :   const auto mu_elem = has_elem ? _mu(elem_face, state) : _mu(neighbor_face, state);
      56    39953472 :   const auto eps_elem = has_elem ? _eps(elem_face, state) : _eps(neighbor_face, state);
      57             : 
      58             :   ADReal mu_neighbor;
      59             :   ADReal eps_neighbor;
      60    39953472 :   if (onBoundary(*_face_info))
      61     1456266 :     mu_face = _mu(singleSidedFaceArg(), state);
      62             :   else
      63             :   {
      64    38497206 :     mu_neighbor = has_elem ? _mu(neighbor_face, state) : _mu(elem_face, state);
      65    38497206 :     eps_neighbor = has_neighbor ? _eps(neighbor_face, state) : _eps(elem_face, state);
      66    38497206 :     interpolate(Moose::FV::InterpMethod::Average, mu_face, mu_elem, mu_neighbor, *_face_info, true);
      67             :   }
      68             : 
      69             :   // Compute face superficial velocity gradient
      70    79906944 :   auto dudn = _var.gradient(makeCDFace(*_face_info), state) * _face_info->normal();
      71             : 
      72    39953472 :   if (populate_a_coeffs)
      73             :   {
      74    37658052 :     if (has_elem)
      75             :     {
      76    37657932 :       const auto dof_number = _face_info->elem().dof_number(_sys.number(), _var.number(), 0);
      77             :       // A gradient is a linear combination of degrees of freedom so it's safe to straight-up index
      78             :       // into the derivatives vector at the dof we care about
      79    37657932 :       _ae = dudn.derivatives()[dof_number];
      80    37657932 :       _ae *= -mu_face;
      81             :     }
      82    37658052 :     if (has_neighbor)
      83             :     {
      84    36304940 :       const auto dof_number = _face_info->neighbor().dof_number(_sys.number(), _var.number(), 0);
      85    36304940 :       _an = dudn.derivatives()[dof_number];
      86    36304940 :       _an *= mu_face;
      87             :     }
      88             :   }
      89             : 
      90             :   // First term of residual
      91             :   ADReal residual = mu_face * dudn;
      92             : 
      93             :   // Get the face porosity gradient separately
      94             :   const auto & grad_eps_face =
      95             :       (has_elem && has_neighbor)
      96    79906944 :           ? MetaPhysicL::raw_value(_eps.gradient(makeCDFace(*_face_info), state))
      97    39953472 :           : MetaPhysicL::raw_value(_eps.gradient(
      98    41411846 :                 makeElemArg(has_elem ? &_face_info->elem() : _face_info->neighborPtr()), state));
      99             : 
     100             :   // Interpolate to get the face value
     101             :   ADReal coeff_face;
     102             :   // At this point, we already computed mu_elem/eps_elem by knowing which element owns the
     103             :   // face, so it is enough to switch between the variable evaluation here
     104             :   const auto coeff_one_side =
     105    39953472 :       mu_elem / eps_elem * (has_elem ? _var(elem_face, state) : _var(neighbor_face, state));
     106    39953472 :   if (onBoundary(*_face_info))
     107     1456266 :     coeff_face = coeff_one_side;
     108             :   else
     109             :   {
     110             :     mooseAssert(has_elem, "We should be defined on the element side if we're not on a boundary");
     111    38497206 :     const auto coeff_neighbor = mu_neighbor / eps_neighbor *
     112    38497206 :                                 (has_elem ? _var(neighbor_face, state) : _var(elem_face, state));
     113    38497206 :     interpolate(Moose::FV::InterpMethod::Average,
     114             :                 coeff_face,
     115             :                 coeff_one_side,
     116             :                 coeff_neighbor,
     117    38497206 :                 *_face_info,
     118             :                 true);
     119             :   }
     120             : 
     121    39953472 :   residual -= coeff_face * grad_eps_face * _normal;
     122             : 
     123    39953472 :   return -residual;
     124             : }

Generated by: LCOV version 1.14