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

Generated by: LCOV version 1.14