LCOV - code coverage report
Current view: top level - src/fvbcs - INSFVTKEDWallFunctionBC.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 853d1f Lines: 57 62 91.9 %
Date: 2025-10-25 20:01:59 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 "INSFVTKEDWallFunctionBC.h"
      11             : #include "Function.h"
      12             : #include "NavierStokesMethods.h"
      13             : #include "NS.h"
      14             : 
      15             : registerMooseObject("NavierStokesApp", INSFVTKEDWallFunctionBC);
      16             : 
      17             : InputParameters
      18          82 : INSFVTKEDWallFunctionBC::validParams()
      19             : {
      20          82 :   InputParameters params = FVDirichletBCBase::validParams();
      21          82 :   params.addClassDescription("Adds Reichardt extrapolated wall values to set up directly the"
      22             :                              "Dirichlet BC for the turbulent kinetic energy dissipation rate.");
      23         164 :   params.addRequiredParam<MooseFunctorName>("u", "The velocity in the x direction.");
      24         164 :   params.addParam<MooseFunctorName>("v", "The velocity in the y direction.");
      25         164 :   params.addParam<MooseFunctorName>("w", "The velocity in the z direction.");
      26          82 :   params.addRequiredParam<MooseFunctorName>(NS::density, "Density");
      27          82 :   params.addRequiredParam<MooseFunctorName>(NS::mu, "Dynamic viscosity.");
      28          82 :   params.addRequiredParam<MooseFunctorName>(NS::mu_t, "The turbulent viscosity.");
      29          82 :   params.addRequiredParam<MooseFunctorName>(NS::TKE, "The turbulent kinetic energy.");
      30         164 :   params.addParam<MooseFunctorName>("C_mu", 0.09, "Coupled turbulent kinetic energy closure.");
      31         164 :   params.addParam<bool>("newton_solve", false, "Whether a Newton nonlinear solve is being used");
      32         164 :   params.addParamNamesToGroup("newton_solve", "Advanced");
      33          82 :   return params;
      34           0 : }
      35             : 
      36          44 : INSFVTKEDWallFunctionBC::INSFVTKEDWallFunctionBC(const InputParameters & params)
      37             :   : FVDirichletBCBase(params),
      38          44 :     _dim(_subproblem.mesh().dimension()),
      39          88 :     _u_var(getFunctor<ADReal>("u")),
      40          44 :     _v_var(params.isParamValid("v") ? &(getFunctor<ADReal>("v")) : nullptr),
      41          44 :     _w_var(params.isParamValid("w") ? &(getFunctor<ADReal>("w")) : nullptr),
      42          44 :     _rho(getFunctor<ADReal>(NS::density)),
      43          44 :     _mu(getFunctor<ADReal>(NS::mu)),
      44          44 :     _mu_t(getFunctor<ADReal>(NS::mu_t)),
      45          44 :     _k(getFunctor<ADReal>(NS::TKE)),
      46          88 :     _C_mu(getFunctor<ADReal>("C_mu")),
      47         132 :     _newton_solve(getParam<bool>("newton_solve"))
      48             : {
      49          44 : }
      50             : 
      51             : ADReal
      52       22600 : INSFVTKEDWallFunctionBC::boundaryValue(const FaceInfo & fi, const Moose::StateArg & state) const
      53             : {
      54       22600 :   const bool use_elem = (fi.faceType(std::make_pair(_var.number(), _var.sys().number())) ==
      55             :                          FaceInfo::VarFaceNeighbors::ELEM);
      56             :   const Real dist = std::abs(
      57       22600 :       ((use_elem ? fi.elemCentroid() : fi.neighborCentroid()) - fi.faceCentroid()) * fi.normal());
      58       22600 :   const Elem * const elem_ptr = use_elem ? fi.elemPtr() : fi.neighborPtr();
      59       22600 :   const auto elem_arg = makeElemArg(elem_ptr);
      60       22600 :   const auto mu = _mu(elem_arg, state);
      61       22600 :   const auto rho = _rho(elem_arg, state);
      62             : 
      63             :   // Assign boundary weights to element
      64             :   // This is based on the theory of linear TKE development for each boundary
      65             :   // This is, it assumes no interaction across turbulence production from boundaries
      66       22600 :   Real weight = 0.0;
      67      113000 :   for (unsigned int i_side = 0; i_side < elem_ptr->n_sides(); ++i_side)
      68       90400 :     weight += static_cast<Real>(_subproblem.mesh().getBoundaryIDs(elem_ptr, i_side).size());
      69             : 
      70             :   // Get the velocity vector
      71       45200 :   ADRealVectorValue velocity(_u_var(elem_arg, state));
      72       22600 :   if (_v_var)
      73           0 :     velocity(1) = (*_v_var)(elem_arg, state);
      74       22600 :   if (_w_var)
      75           0 :     velocity(2) = (*_w_var)(elem_arg, state);
      76             : 
      77             :   // Compute the velocity and direction of the velocity component that is parallel to the wall
      78             :   const ADReal parallel_speed =
      79       67800 :       NS::computeSpeed<ADReal>(velocity - velocity * (fi.normal()) * (fi.normal()));
      80             : 
      81             :   // Get friction velocity
      82       22600 :   const ADReal u_star = NS::findUStar<ADReal>(mu, rho, parallel_speed, dist);
      83             : 
      84             :   // Get associated non-dimensional wall distance
      85       22600 :   const ADReal y_plus = dist * u_star * rho / mu;
      86             : 
      87       22600 :   const auto TKE = _k(elem_arg, state);
      88             : 
      89       22600 :   if (y_plus <= 5.0) // sub-laminar layer
      90             :   {
      91       19222 :     const auto laminar_value = 2.0 * weight * TKE * mu / std::pow(dist, 2);
      92       19222 :     if (!_newton_solve)
      93       19222 :       return laminar_value;
      94             :     else
      95             :       // Additional zero term to make sure new derivatives are not introduced as y_plus
      96             :       // changes
      97           0 :       return laminar_value + 0 * _mu_t(elem_arg, state);
      98             :   }
      99        3378 :   else if (y_plus >= 30.0) // log-layer
     100             :   {
     101         248 :     const auto turbulent_value = weight * _C_mu(elem_arg, state) * std::pow(std::abs(TKE), 1.5) /
     102         248 :                                  (_mu_t(elem_arg, state) * dist);
     103         248 :     if (!_newton_solve)
     104         248 :       return turbulent_value;
     105             :     else
     106             :       // Additional zero term to make sure new derivatives are not introduced as y_plus changes
     107           0 :       return turbulent_value + 0 * mu;
     108             :   }
     109             :   else // blending function
     110             :   {
     111        3130 :     const auto laminar_value = 2.0 * weight * TKE * mu / std::pow(dist, 2);
     112        3130 :     const auto turbulent_value = weight * _C_mu(elem_arg, state) * std::pow(std::abs(TKE), 1.5) /
     113        3130 :                                  (_mu_t(elem_arg, state) * dist);
     114        6260 :     const auto interpolation_coef = (y_plus - 5.0) / 25.0;
     115        3130 :     return (interpolation_coef * (turbulent_value - laminar_value) + laminar_value);
     116             :   }
     117             : }

Generated by: LCOV version 1.14