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

Generated by: LCOV version 1.14