LCOV - code coverage report
Current view: top level - src/fvbcs - INSFVTurbulentTemperatureWallFunction.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 853d1f Lines: 77 92 83.7 %
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 "INSFVTurbulentTemperatureWallFunction.h"
      11             : #include "NavierStokesMethods.h"
      12             : #include "NS.h"
      13             : 
      14             : registerADMooseObject("NavierStokesApp", INSFVTurbulentTemperatureWallFunction);
      15             : 
      16             : InputParameters
      17         366 : INSFVTurbulentTemperatureWallFunction::validParams()
      18             : {
      19         366 :   InputParameters params = FVFluxBC::validParams();
      20             : 
      21         366 :   params.addClassDescription("Adds turbulent temperature wall function.");
      22         732 :   params.addRequiredParam<MooseFunctorName>("T_w", "The wall temperature.");
      23         732 :   params.addRequiredParam<MooseFunctorName>("u", "The velocity in the x direction.");
      24         732 :   params.addParam<MooseFunctorName>("v", "The velocity in the y direction.");
      25         732 :   params.addParam<MooseFunctorName>("w", "The velocity in the z direction.");
      26         366 :   params.addRequiredParam<MooseFunctorName>(NS::density, "Density");
      27         366 :   params.addRequiredParam<MooseFunctorName>(NS::mu, "Dynamic viscosity.");
      28         366 :   params.addRequiredParam<MooseFunctorName>(NS::cp, "The specific heat at constant pressure.");
      29         366 :   params.addParam<MooseFunctorName>(NS::kappa, "The thermal conductivity.");
      30         732 :   params.addParam<MooseFunctorName>("Pr_t", 0.58, "The turbulent Prandtl number.");
      31         366 :   params.addParam<MooseFunctorName>(NS::TKE, "Turbulent kinetic energy functor.");
      32         732 :   params.addParam<Real>("C_mu", 0.09, "Coupled turbulent kinetic energy closure.");
      33         732 :   MooseEnum wall_treatment("eq_newton eq_incremental eq_linearized neq", "neq");
      34         732 :   params.addParam<MooseEnum>(
      35             :       "wall_treatment", wall_treatment, "The method used for computing the wall functions");
      36             : 
      37         732 :   params.addParam<bool>("newton_solve", false, "Whether a Newton nonlinear solve is being used");
      38         732 :   params.addParamNamesToGroup("newton_solve", "Advanced");
      39         366 :   return params;
      40         366 : }
      41             : 
      42         198 : INSFVTurbulentTemperatureWallFunction::INSFVTurbulentTemperatureWallFunction(
      43         198 :     const InputParameters & parameters)
      44             :   : FVFluxBC(parameters),
      45         198 :     _dim(_subproblem.mesh().dimension()),
      46         396 :     _T_w(getFunctor<ADReal>("T_w")),
      47         396 :     _u_var(getFunctor<ADReal>("u")),
      48         594 :     _v_var(parameters.isParamValid("v") ? &(getFunctor<ADReal>("v")) : nullptr),
      49         198 :     _w_var(parameters.isParamValid("w") ? &(getFunctor<ADReal>("w")) : nullptr),
      50         198 :     _rho(getFunctor<ADReal>(NS::density)),
      51         198 :     _mu(getFunctor<ADReal>(NS::mu)),
      52         198 :     _cp(getFunctor<ADReal>(NS::cp)),
      53         198 :     _kappa(getFunctor<ADReal>(NS::kappa)),
      54         396 :     _Pr_t(getFunctor<ADReal>("Pr_t")),
      55         198 :     _k(getFunctor<ADReal>(NS::TKE)),
      56         396 :     _C_mu(getParam<Real>("C_mu")),
      57         396 :     _wall_treatment(getParam<MooseEnum>("wall_treatment")),
      58         594 :     _newton_solve(getParam<bool>("newton_solve"))
      59             : {
      60         198 : }
      61             : 
      62             : ADReal
      63       16984 : INSFVTurbulentTemperatureWallFunction::computeQpResidual()
      64             : {
      65             :   // Useful parameters
      66       16984 :   const FaceInfo & fi = *_face_info;
      67             :   // if on an internal face (internal to the mesh, but an external boundary of the flow area),
      68             :   // we have to select the element on which the flow variables / temperature are defined
      69       16984 :   const bool use_elem = (_face_type == FaceInfo::VarFaceNeighbors::ELEM);
      70             :   const Real wall_dist = std::abs(
      71       16984 :       ((use_elem ? fi.elemCentroid() : fi.neighborCentroid()) - fi.faceCentroid()) * fi.normal());
      72       16984 :   const Elem * const elem_ptr = use_elem ? fi.elemPtr() : fi.neighborPtr();
      73       16984 :   const auto elem_arg = makeElemArg(elem_ptr);
      74       16984 :   const auto state = determineState();
      75             :   const auto old_state = Moose::StateArg(1, Moose::SolutionIterationType::Nonlinear);
      76       16984 :   const auto mu = _mu(elem_arg, state);
      77       16984 :   const auto rho = _rho(elem_arg, state);
      78       16984 :   const auto cp = _cp(elem_arg, state);
      79       16984 :   const auto kappa = _kappa(elem_arg, state);
      80             : 
      81             :   // Get the velocity vector
      82       33968 :   ADRealVectorValue velocity(_u_var(elem_arg, state));
      83       16984 :   if (_v_var)
      84       16984 :     velocity(1) = (*_v_var)(elem_arg, state);
      85       16984 :   if (_w_var)
      86           0 :     velocity(2) = (*_w_var)(elem_arg, state);
      87             : 
      88             :   // Compute the velocity and direction of the velocity component that is parallel to the wall
      89             :   const ADReal parallel_speed =
      90       50952 :       NS::computeSpeed<ADReal>(velocity - velocity * (fi.normal()) * (fi.normal()));
      91             : 
      92             :   // Computing friction velocity and y+
      93             :   ADReal u_tau, y_plus;
      94             : 
      95       16984 :   if (_wall_treatment == "eq_newton")
      96             :   {
      97             :     // Full Newton-Raphson solve to find the wall quantities from the law of the wall
      98           0 :     u_tau = NS::findUStar<ADReal>(mu, rho, parallel_speed, wall_dist);
      99           0 :     y_plus = wall_dist * u_tau * rho / mu;
     100             :   }
     101       16984 :   else if (_wall_treatment == "eq_incremental")
     102             :   {
     103             :     // Incremental solve on y_plus to get the near-wall quantities
     104           0 :     y_plus = NS::findyPlus<ADReal>(mu, rho, std::max(parallel_speed, 1e-10), wall_dist);
     105           0 :     u_tau = parallel_speed / (std::log(std::max(NS::E_turb_constant * y_plus, 1.0 + 1e-4)) /
     106           0 :                               NS::von_karman_constant);
     107             :   }
     108       16984 :   else if (_wall_treatment == "eq_linearized")
     109             :   {
     110             :     // Linearized approximation to the wall function to find the near-wall quantities faster
     111       16984 :     const ADReal a_c = 1 / NS::von_karman_constant;
     112       33968 :     const ADReal b_c = 1.0 / NS::von_karman_constant *
     113       50952 :                        (std::log(NS::E_turb_constant * std::max(wall_dist, 1.0) / mu) + 1.0);
     114       16984 :     const ADReal c_c = parallel_speed;
     115             : 
     116       84920 :     u_tau = (-b_c + std::sqrt(std::pow(b_c, 2) + 4.0 * a_c * c_c)) / (2.0 * a_c);
     117       16984 :     y_plus = wall_dist * u_tau * rho / mu;
     118             :   }
     119           0 :   else if (_wall_treatment == "neq")
     120             :   {
     121             :     // Assign non-equilibrium wall function value
     122           0 :     y_plus = wall_dist * std::sqrt(std::sqrt(_C_mu) * _k(elem_arg, old_state)) * rho / mu;
     123           0 :     u_tau = parallel_speed / (std::log(std::max(NS::E_turb_constant * y_plus, 1.0 + 1e-4)) /
     124           0 :                               NS::von_karman_constant);
     125             :   }
     126             : 
     127             :   ADReal alpha;
     128       16984 :   if (y_plus <= 5.0) // sub-laminar layer
     129             :   {
     130       16723 :     alpha = kappa / (rho * cp);
     131             :   }
     132         261 :   else if (y_plus >= 30.0) // log-layer
     133             :   {
     134           0 :     const auto Pr = cp * mu / kappa;
     135           0 :     const auto Pr_ratio = Pr / _Pr_t(elem_arg, state);
     136             :     const auto jayatilleke_P =
     137           0 :         9.24 * (std::pow(Pr_ratio, 0.75) - 1.0) * (1.0 + 0.28 * std::exp(-0.007 * Pr_ratio));
     138             :     const auto wall_scaling =
     139           0 :         1.0 / NS::von_karman_constant * std::log(NS::E_turb_constant * y_plus) + jayatilleke_P;
     140           0 :     alpha = u_tau * wall_dist / (_Pr_t(elem_arg, state) * wall_scaling);
     141             :   }
     142             :   else // buffer layer
     143             :   {
     144         261 :     const auto alpha_lam = kappa / (rho * cp);
     145         261 :     const auto Pr = cp * mu / kappa;
     146         261 :     const auto Pr_t = _Pr_t(elem_arg, state);
     147             :     const auto Pr_ratio = Pr / Pr_t;
     148             :     const auto jayatilleke_P =
     149        1566 :         9.24 * (std::pow(Pr_ratio, 0.75) - 1.0) * (1.0 + 0.28 * std::exp(-0.007 * Pr_ratio));
     150             :     const auto wall_scaling =
     151         522 :         1.0 / NS::von_karman_constant * std::log(NS::E_turb_constant * y_plus) + jayatilleke_P;
     152         261 :     const auto alpha_turb = u_tau * wall_dist / (Pr_t * wall_scaling);
     153         261 :     const auto blending_function = (y_plus - 5.0) / 25.0;
     154         522 :     alpha = blending_function * alpha_turb + (1.0 - blending_function) * alpha_lam;
     155             :   }
     156             : 
     157             :   // To make sure new derivatives are not introduced as the solve progresses
     158       16984 :   if (_newton_solve)
     159       33672 :     alpha += 0 * kappa * (rho * cp) + 0 * u_tau * _Pr_t(elem_arg, state) * y_plus;
     160             : 
     161       16984 :   const auto face_arg = singleSidedFaceArg();
     162       50952 :   return -rho * cp * alpha * (_T_w(face_arg, state) - _var(elem_arg, state)) / wall_dist;
     163             : }

Generated by: LCOV version 1.14