LCOV - code coverage report
Current view: top level - src/linearfvkernels - LinearFVRZViscousSource.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: #32971 (54bef8) with base c6cf66 Lines: 58 63 92.1 %
Date: 2026-05-29 20:37:52 Functions: 6 6 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 "LinearFVRZViscousSource.h"
      11             : #include "FEProblemBase.h"
      12             : #include "MooseLinearVariableFV.h"
      13             : #include "NS.h"
      14             : 
      15             : #include "libmesh/utility.h"
      16             : 
      17             : registerMooseObject("NavierStokesApp", LinearFVRZViscousSource);
      18             : 
      19             : InputParameters
      20         108 : LinearFVRZViscousSource::validParams()
      21             : {
      22         108 :   InputParameters params = LinearFVElementalKernel::validParams();
      23         108 :   params.addClassDescription(
      24             :       "Adds the axisymmetric viscous source term mu * u_r / r^2 to the FV momentum equations.");
      25         108 :   params.addRequiredParam<MooseFunctorName>(NS::mu, "Dynamic viscosity functor.");
      26         216 :   MooseEnum component("x=0 y=1 z=2");
      27         216 :   params.addRequiredParam<MooseEnum>(
      28             :       "momentum_component", component, "Momentum component this kernel contributes to.");
      29         216 :   params.addParam<SolverVariableName>("u", "The velocity in the x direction.");
      30         216 :   params.addParam<SolverVariableName>("v", "The velocity in the y direction.");
      31         216 :   params.addParam<bool>(
      32             :       "use_deviatoric_terms",
      33         216 :       false,
      34             :       "Include the deviatoric correction (-2/3 div(u)) in the axisymmetric term.");
      35         108 :   return params;
      36         108 : }
      37             : 
      38          54 : LinearFVRZViscousSource::LinearFVRZViscousSource(const InputParameters & params)
      39             :   : LinearFVElementalKernel(params),
      40         108 :     _mu(getFunctor<Real>(NS::mu)),
      41         108 :     _component(getParam<MooseEnum>("momentum_component")),
      42          54 :     _rz_radial_coord(_subproblem.getAxisymmetricRadialCoord()),
      43          54 :     _dim(_subproblem.mesh().dimension()),
      44         108 :     _use_deviatoric_terms(getParam<bool>("use_deviatoric_terms")),
      45          54 :     _coord_type(getBlockCoordSystem()),
      46          54 :     _stress_multiplier(_use_deviatoric_terms ? 2.0 : 1.0),
      47          54 :     _velocity_vars{nullptr, nullptr}
      48             : {
      49          54 :   if (_coord_type != Moose::CoordinateSystemType::COORD_RZ)
      50           0 :     paramError("block", "LinearFVRZViscousSource is only valid on RZ coordinate systems.");
      51             : 
      52          54 :   if (_component != _rz_radial_coord)
      53           0 :     paramError("momentum_component", "LinearFVRZViscousSource must act on the radial component.");
      54             : 
      55          54 :   if (_use_deviatoric_terms)
      56          24 :     _var.computeCellGradients();
      57             : 
      58             :   const auto get_velocity_var =
      59          48 :       [this](const std::string & param_name) -> MooseLinearVariableFVReal *
      60             :   {
      61          48 :     auto & var = _fe_problem.getVariable(_tid, getParam<SolverVariableName>(param_name));
      62          48 :     auto ptr = dynamic_cast<MooseLinearVariableFVReal *>(&var);
      63          48 :     if (!ptr)
      64           0 :       paramError(param_name, "The supplied variable must be a MooseLinearVariableFVReal.");
      65          48 :     return ptr;
      66          54 :   };
      67             : 
      68          54 :   if (_use_deviatoric_terms)
      69             :   {
      70          48 :     if (isParamValid("u"))
      71          24 :       _velocity_vars[0] = get_velocity_var("u");
      72          48 :     if (isParamValid("v"))
      73          24 :       _velocity_vars[1] = get_velocity_var("v");
      74             : 
      75          24 :     if (!_velocity_vars[0])
      76           0 :       paramError("u", "The x-velocity must be provided when using deviatoric terms.");
      77          24 :     if (!_velocity_vars[1])
      78           0 :       paramError("v", "The y-velocity must be provided when using deviatoric terms.");
      79             : 
      80          72 :     for (const auto dir : make_range(_dim))
      81          48 :       _velocity_vars[dir]->computeCellGradients();
      82             :   }
      83          54 : }
      84             : 
      85             : Real
      86      800724 : LinearFVRZViscousSource::computeMatrixContribution()
      87             : {
      88      800724 :   const Real r = _current_elem_info->centroid()(_rz_radial_coord);
      89             :   mooseAssert(r > 0, "Axisymmetric control volumes should not sit on the axis (r = 0).");
      90             : 
      91      800724 :   const Real mu = _mu(makeElemArg(_current_elem_info->elem()), determineState());
      92      800724 :   return mu * _stress_multiplier * _current_elem_volume / (r * r);
      93             : }
      94             : 
      95             : Real
      96      800724 : LinearFVRZViscousSource::computeRightHandSideContribution()
      97             : {
      98      800724 :   if (!_use_deviatoric_terms)
      99             :     return 0.0;
     100             : 
     101       63804 :   const auto state = determineState();
     102             :   Real divergence = 0.0;
     103      191412 :   for (const auto dir : make_range(_dim))
     104      127608 :     divergence += velocityVar(dir).gradSln(*_current_elem_info, state)(dir);
     105             : 
     106       63804 :   const Real r = _current_elem_info->centroid()(_rz_radial_coord);
     107             :   mooseAssert(r > 0, "Axisymmetric control volumes should not sit on the axis (r = 0).");
     108             : 
     109       63804 :   const Real radial_value = velocityVar(_rz_radial_coord).getElemValue(*_current_elem_info, state);
     110       63804 :   divergence += radial_value / r;
     111             : 
     112       63804 :   const auto elem_arg = makeElemArg(_current_elem_info->elem());
     113       63804 :   const Real mu = _mu(elem_arg, state);
     114             : 
     115       63804 :   return (2.0 / 3.0) * mu * divergence * _current_elem_volume / r;
     116             : }
     117             : 
     118             : const MooseLinearVariableFVReal &
     119      191412 : LinearFVRZViscousSource::velocityVar(unsigned int dir) const
     120             : {
     121             :   mooseAssert(dir < _velocity_vars.size() && _velocity_vars[dir],
     122             :               "Velocity variable for requested direction is not available.");
     123      191412 :   return *_velocity_vars[dir];
     124             : }

Generated by: LCOV version 1.14