LCOV - code coverage report
Current view: top level - src/fvkernels - WCNSFVMixingLengthEnergyDiffusion.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: ba1ead Lines: 51 58 87.9 %
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 "WCNSFVMixingLengthEnergyDiffusion.h"
      11             : #include "NS.h"
      12             : #include "MathFVUtils.h"
      13             : 
      14             : registerMooseObject("NavierStokesApp", WCNSFVMixingLengthEnergyDiffusion);
      15             : 
      16             : InputParameters
      17          36 : WCNSFVMixingLengthEnergyDiffusion::validParams()
      18             : {
      19          36 :   InputParameters params = FVFluxKernel::validParams();
      20          36 :   params += FVDiffusionInterpolationInterface::validParams();
      21          36 :   params.addClassDescription("Computes the turbulent diffusive flux that appears in "
      22             :                              "Reynolds-averaged fluid energy conservation equations.");
      23          72 :   params.addRequiredParam<MooseFunctorName>("u", "The velocity in the x direction.");
      24          72 :   params.addParam<MooseFunctorName>("v", "The velocity in the y direction.");
      25          72 :   params.addParam<MooseFunctorName>("w", "The velocity in the z direction.");
      26          72 :   params.addRequiredParam<MooseFunctorName>("mixing_length", "The turbulent mixing length.");
      27          72 :   params.addRequiredParam<Real>(
      28             :       "schmidt_number",
      29             :       "The turbulent Schmidt number (or turbulent Prandtl number if the passive scalar is energy) "
      30             :       "that relates the turbulent scalar diffusivity to the turbulent momentum diffusivity.");
      31          36 :   params.addRequiredParam<MooseFunctorName>(NS::density, "Density");
      32          72 :   params.addRequiredParam<MooseFunctorName>(NS::cp, "Specific heat capacity");
      33             : 
      34             :   // We add the relationship manager here, this will select the right number of
      35             :   // ghosting layers depending on the chosen interpolation method
      36          72 :   params.addRelationshipManager(
      37             :       "ElementSideNeighborLayers",
      38             :       Moose::RelationshipManagerType::GEOMETRIC | Moose::RelationshipManagerType::ALGEBRAIC |
      39             :           Moose::RelationshipManagerType::COUPLING,
      40             :       [](const InputParameters & obj_params, InputParameters & rm_params)
      41          27 :       { FVRelationshipManagerInterface::setRMParamsDiffusion(obj_params, rm_params, 3); });
      42             : 
      43          36 :   params.set<unsigned short>("ghost_layers") = 2;
      44          36 :   return params;
      45           0 : }
      46             : 
      47          20 : WCNSFVMixingLengthEnergyDiffusion::WCNSFVMixingLengthEnergyDiffusion(const InputParameters & params)
      48             :   : FVFluxKernel(params),
      49             :     FVDiffusionInterpolationInterface(params),
      50          20 :     _dim(_subproblem.mesh().dimension()),
      51          40 :     _u(getFunctor<ADReal>("u")),
      52          80 :     _v(isParamValid("v") ? &getFunctor<ADReal>("v") : nullptr),
      53          40 :     _w(isParamValid("w") ? &getFunctor<ADReal>("w") : nullptr),
      54          20 :     _rho(getFunctor<ADReal>(NS::density)),
      55          20 :     _cp(getFunctor<ADReal>(NS::cp)),
      56          40 :     _mixing_len(getFunctor<ADReal>("mixing_length")),
      57          60 :     _schmidt_number(getParam<Real>("schmidt_number"))
      58             : {
      59          20 :   if (_dim >= 2 && !_v)
      60           0 :     mooseError(
      61             :         "In two or more dimensions, the v velocity must be supplied using the 'v' parameter");
      62          20 :   if (_dim >= 3 && !_w)
      63           0 :     mooseError("In three dimensions, the w velocity must be supplied using the 'w' parameter");
      64          20 : }
      65             : 
      66             : ADReal
      67      210156 : WCNSFVMixingLengthEnergyDiffusion::computeQpResidual()
      68             : {
      69             :   constexpr Real offset = 1e-15; // prevents explosion of sqrt(x) derivative to infinity
      70             : 
      71      210156 :   const auto face = makeCDFace(*_face_info);
      72      210156 :   const auto state = determineState();
      73             : 
      74      210156 :   const auto grad_u = _u.gradient(face, state);
      75      420312 :   ADReal symmetric_strain_tensor_norm = 2.0 * Utility::pow<2>(grad_u(0));
      76      210156 :   if (_dim >= 2)
      77             :   {
      78      210156 :     const auto grad_v = _v->gradient(face, state);
      79             :     symmetric_strain_tensor_norm +=
      80      420312 :         2.0 * Utility::pow<2>(grad_v(1)) + Utility::pow<2>(grad_v(0) + grad_u(1));
      81      210156 :     if (_dim >= 3)
      82             :     {
      83           0 :       const auto grad_w = _w->gradient(face, state);
      84           0 :       symmetric_strain_tensor_norm += 2.0 * Utility::pow<2>(grad_w(2)) +
      85           0 :                                       Utility::pow<2>(grad_u(2) + grad_w(0)) +
      86           0 :                                       Utility::pow<2>(grad_v(2) + grad_w(1));
      87             :     }
      88             :   }
      89             : 
      90      210156 :   symmetric_strain_tensor_norm = std::sqrt(symmetric_strain_tensor_norm + offset);
      91             : 
      92             :   // Interpolate the mixing length to the face
      93      210156 :   ADReal mixing_len = _mixing_len(face, state);
      94             : 
      95             :   // Compute the eddy diffusivity for momentum
      96      210156 :   ADReal eddy_diff = symmetric_strain_tensor_norm * mixing_len * mixing_len;
      97             : 
      98             :   // Use the turbulent Schmidt/Prandtl number to get the eddy diffusivity for
      99             :   // the scalar variable
     100      210156 :   eddy_diff /= _schmidt_number;
     101             : 
     102      210156 :   const auto dTdn = gradUDotNormal(state, _correct_skewness);
     103             : 
     104             :   ADReal rho_cp_face;
     105      210156 :   if (onBoundary(*_face_info))
     106             :   {
     107        5652 :     const auto ssf = singleSidedFaceArg();
     108       11304 :     rho_cp_face = _rho(ssf, state) * _cp(ssf, state);
     109             :   }
     110             :   else
     111             :   {
     112             :     // Interpolate the heat capacity
     113      204504 :     const auto face_elem = elemArg();
     114      204504 :     const auto face_neighbor = neighborArg();
     115      204504 :     interpolate(Moose::FV::InterpMethod::Average,
     116             :                 rho_cp_face,
     117      204504 :                 _rho(face_elem, state) * _cp(face_elem, state),
     118      409008 :                 _rho(face_neighbor, state) * _cp(face_neighbor, state),
     119      204504 :                 *_face_info,
     120             :                 true);
     121             :   }
     122             : 
     123      420312 :   return -1 * eddy_diff * rho_cp_face * dTdn;
     124             : }

Generated by: LCOV version 1.14