LCOV - code coverage report
Current view: top level - src/physics - WCNSFVTurbulencePhysics.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 9fc4b0 Lines: 557 608 91.6 %
Date: 2025-08-14 10:14:56 Functions: 19 20 95.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 "WCNSFVTurbulencePhysics.h"
      11             : #include "WCNSFVFlowPhysics.h"
      12             : #include "WCNSFVFluidHeatTransferPhysics.h"
      13             : #include "WCNSFVScalarTransportPhysics.h"
      14             : #include "WCNSFVCoupledAdvectionPhysicsHelper.h"
      15             : #include "INSFVTurbulentViscosityWallFunction.h"
      16             : #include "INSFVTKESourceSink.h"
      17             : #include "NSFVBase.h"
      18             : 
      19             : registerNavierStokesPhysicsBaseTasks("NavierStokesApp", WCNSFVTurbulencePhysics);
      20             : registerMooseAction("NavierStokesApp", WCNSFVTurbulencePhysics, "get_turbulence_physics");
      21             : registerMooseAction("NavierStokesApp", WCNSFVTurbulencePhysics, "add_variable");
      22             : registerMooseAction("NavierStokesApp", WCNSFVTurbulencePhysics, "add_fv_kernel");
      23             : registerMooseAction("NavierStokesApp", WCNSFVTurbulencePhysics, "add_fv_bc");
      24             : registerMooseAction("NavierStokesApp", WCNSFVTurbulencePhysics, "add_ic");
      25             : registerMooseAction("NavierStokesApp", WCNSFVTurbulencePhysics, "add_aux_variable");
      26             : registerMooseAction("NavierStokesApp", WCNSFVTurbulencePhysics, "add_aux_kernel");
      27             : registerMooseAction("NavierStokesApp", WCNSFVTurbulencePhysics, "add_material");
      28             : 
      29             : InputParameters
      30        1097 : WCNSFVTurbulencePhysics::validParams()
      31             : {
      32        1097 :   InputParameters params = NavierStokesPhysicsBase::validParams();
      33        1097 :   params += WCNSFVCoupledAdvectionPhysicsHelper::validParams();
      34        1097 :   params.addClassDescription(
      35             :       "Define a turbulence model for a incompressible or weakly-compressible Navier Stokes "
      36             :       "flow with a finite volume discretization");
      37             : 
      38        2194 :   MooseEnum turbulence_type("mixing-length k-epsilon none", "none");
      39        2194 :   params.addParam<MooseEnum>(
      40             :       "turbulence_handling",
      41             :       turbulence_type,
      42             :       "The way turbulent diffusivities are determined in the turbulent regime.");
      43        1097 :   params += NSFVBase::commonTurbulenceParams();
      44        1097 :   params.transferParam<bool>(NSFVBase::validParams(), "mixing_length_two_term_bc_expansion");
      45             : 
      46             :   // TODO Added to facilitate transition, remove default once NavierStokesFV action is removed
      47        2194 :   params.addParam<AuxVariableName>(
      48             :       "mixing_length_name", "mixing_length", "Name of the mixing length auxiliary variable");
      49        2194 :   params.deprecateParam("mixing_length_walls", "turbulence_walls", "");
      50             : 
      51             :   // Not implemented, re-enable with k-epsilon
      52        1097 :   params.suppressParameter<MooseEnum>("preconditioning");
      53             : 
      54             :   // K-Epsilon parameters
      55        2194 :   params.addParam<MooseFunctorName>(
      56             :       "tke_name", NS::TKE, "Name of the turbulent kinetic energy variable");
      57        2194 :   params.addParam<MooseFunctorName>(
      58             :       "tked_name", NS::TKED, "Name of the turbulent kinetic energy dissipation variable");
      59        2194 :   params.addParam<FunctionName>(
      60             :       "initial_tke", "0", "Initial value for the turbulence kinetic energy");
      61        2194 :   params.addParam<FunctionName>(
      62             :       "initial_tked", "0", "Initial value for the turbulence kinetic energy dissipation");
      63        2194 :   params.addParam<FunctionName>("initial_mu_t", "Initial value for the turbulence viscosity");
      64             : 
      65        2194 :   params.addParam<Real>("C1_eps",
      66             :                         "C1 coefficient for the turbulent kinetic energy dissipation equation");
      67        2194 :   params.addParam<Real>("C2_eps",
      68             :                         "C2 coefficient for the turbulent kinetic energy dissipation equation");
      69        2194 :   params.addParam<MooseFunctorName>(
      70             :       "sigma_k", "Scaling coefficient for the turbulent kinetic energy diffusion term");
      71        2194 :   params.addParam<MooseFunctorName>(
      72             :       "sigma_eps",
      73             :       "Scaling coefficient for the turbulent kinetic energy dissipation diffusion term");
      74        1097 :   params.addParam<MooseFunctorName>(
      75             :       NS::turbulent_Prandtl, NS::turbulent_Prandtl, "Turbulent Prandtl number");
      76        1097 :   params.transferParam<Real>(INSFVTKESourceSink::validParams(), "C_pl");
      77             : 
      78             :   // Boundary parameters
      79        2194 :   params.addParam<bool>("bulk_wall_treatment", true, "Whether to treat the wall cell as bulk");
      80        2194 :   MooseEnum wall_treatment("eq_newton eq_incremental eq_linearized neq", "neq");
      81        2194 :   params.addParam<MooseEnum>("wall_treatment_eps",
      82             :                              wall_treatment,
      83             :                              "The method used for computing the epsilon wall functions");
      84        2194 :   params.addParam<MooseEnum>("wall_treatment_T",
      85             :                              wall_treatment,
      86             :                              "The method used for computing the temperature wall functions");
      87        1097 :   params.transferParam<Real>(INSFVTurbulentViscosityWallFunction::validParams(), "C_mu");
      88             : 
      89             :   // K-Epsilon numerical scheme parameters
      90        2194 :   MooseEnum face_interpol_types("average skewness-corrected", "average");
      91        2194 :   MooseEnum adv_interpol_types("average upwind", "upwind");
      92        3291 :   params.addRangeCheckedParam<Real>(
      93             :       "tke_scaling",
      94        2194 :       1.0,
      95             :       "tke_scaling > 0.0",
      96             :       "The scaling factor for the turbulent kinetic energy equation.");
      97        2194 :   params.addParam<MooseEnum>("tke_face_interpolation",
      98             :                              face_interpol_types,
      99             :                              "The numerical scheme to interpolate the TKE to the "
     100             :                              "face (separate from the advected quantity interpolation).");
     101        2194 :   params.addParam<MooseEnum>("tke_advection_interpolation",
     102             :                              adv_interpol_types,
     103             :                              "The numerical scheme to interpolate the TKE to the "
     104             :                              "face when in the advection kernel.");
     105             :   // Better Jacobian if not linearizing sink and sources
     106        2194 :   params.addParam<bool>("linearize_sink_sources", false, "Whether to linearize the source term");
     107             :   // Better convergence on some cases when neglecting advection derivatives
     108        2194 :   params.addParam<bool>(
     109             :       "neglect_advection_derivatives",
     110        2194 :       false,
     111             :       "Whether to remove the off-diagonal velocity term in the TKE and TKED advection term");
     112        2194 :   params.addParam<bool>(
     113             :       "tke_two_term_bc_expansion",
     114        2194 :       false,
     115             :       "If a two-term Taylor expansion is needed for the determination of the boundary values"
     116             :       "of the turbulent kinetic energy.");
     117        3291 :   params.addRangeCheckedParam<Real>(
     118             :       "tked_scaling",
     119        2194 :       1.0,
     120             :       "tked_scaling > 0.0",
     121             :       "The scaling factor for the turbulent kinetic energy dissipation equation.");
     122        2194 :   params.addParam<MooseEnum>("tked_face_interpolation",
     123             :                              face_interpol_types,
     124             :                              "The numerical scheme to interpolate the TKED to the "
     125             :                              "face (separate from the advected quantity interpolation).");
     126        2194 :   params.addParam<MooseEnum>("tked_advection_interpolation",
     127             :                              adv_interpol_types,
     128             :                              "The numerical scheme to interpolate the TKED to the "
     129             :                              "face when in the advection kernel.");
     130        2194 :   params.addParam<bool>(
     131             :       "tked_two_term_bc_expansion",
     132        2194 :       false,
     133             :       "If a two-term Taylor expansion is needed for the determination of the boundary values"
     134             :       "of the turbulent kinetic energy dissipation.");
     135        2194 :   params.addParam<bool>(
     136             :       "turbulent_viscosity_two_term_bc_expansion",
     137        2194 :       true,
     138             :       "If a two-term Taylor expansion is needed for the determination of the boundary values"
     139             :       "of the turbulent viscosity.");
     140        2194 :   MooseEnum coeff_interp_method("average harmonic", "harmonic");
     141        2194 :   params.addParam<MooseEnum>("turbulent_viscosity_interp_method",
     142             :                              coeff_interp_method,
     143             :                              "Face interpolation method for the turbulent viscosity");
     144        2194 :   params.addParam<bool>("mu_t_as_aux_variable",
     145        2194 :                         false,
     146             :                         "Whether to use an auxiliary variable instead of a functor material "
     147             :                         "property for the turbulent viscosity");
     148        2194 :   params.addParam<bool>("output_mu_t", true, "Whether to add mu_t to the field outputs");
     149        2194 :   params.addParam<bool>("k_t_as_aux_variable",
     150        2194 :                         false,
     151             :                         "Whether to use an auxiliary variable for the turbulent conductivity");
     152             : 
     153             :   // Add the coupled physics
     154             :   // TODO Remove the defaults once NavierStokesFV action is removed
     155             :   // It is a little risky right now because the user could forget to pass the parameter and
     156             :   // be missing the influence of turbulence on either of these physics. There is a check in the
     157             :   // constructor to present this from happening
     158        2194 :   params.addParam<PhysicsName>(
     159             :       "fluid_heat_transfer_physics",
     160             :       "NavierStokesFV",
     161             :       "WCNSFVFluidHeatTransferPhysics generating the heat advection equations");
     162        2194 :   params.addParam<PhysicsName>(
     163             :       "scalar_transport_physics",
     164             :       "NavierStokesFV",
     165             :       "WCNSFVScalarTransportPhysics generating the scalar advection equations");
     166             : 
     167             :   // Parameter groups
     168        2194 :   params.addParamNamesToGroup("mixing_length_name mixing_length_two_term_bc_expansion",
     169             :                               "Mixing length model");
     170        2194 :   params.addParamNamesToGroup("fluid_heat_transfer_physics turbulent_prandtl "
     171             :                               "scalar_transport_physics Sc_t",
     172             :                               "Coupled Physics");
     173        2194 :   params.addParamNamesToGroup("initial_tke initial_tked C1_eps C2_eps sigma_k sigma_eps",
     174             :                               "K-Epsilon model");
     175        2194 :   params.addParamNamesToGroup("C_mu bulk_wall_treatment wall_treatment_eps wall_treatment_T",
     176             :                               "K-Epsilon wall function");
     177        2194 :   params.addParamNamesToGroup(
     178             :       "tke_scaling tke_face_interpolation tke_two_term_bc_expansion tked_scaling "
     179             :       "tked_face_interpolation tked_two_term_bc_expansion "
     180             :       "turbulent_viscosity_two_term_bc_expansion turbulent_viscosity_interp_method "
     181             :       "mu_t_as_aux_variable k_t_as_aux_variable linearize_sink_sources",
     182             :       "K-Epsilon model numerical");
     183             : 
     184        1097 :   return params;
     185        1097 : }
     186             : 
     187        1097 : WCNSFVTurbulencePhysics::WCNSFVTurbulencePhysics(const InputParameters & parameters)
     188             :   : NavierStokesPhysicsBase(parameters),
     189             :     WCNSFVCoupledAdvectionPhysicsHelper(this),
     190        1097 :     _turbulence_model(getParam<MooseEnum>("turbulence_handling")),
     191        2194 :     _mixing_length_name(getParam<AuxVariableName>("mixing_length_name")),
     192        2194 :     _turbulence_walls(getParam<std::vector<BoundaryName>>("turbulence_walls")),
     193        2194 :     _wall_treatment_eps(getParam<MooseEnum>("wall_treatment_eps")),
     194        2194 :     _wall_treatment_temp(getParam<MooseEnum>("wall_treatment_T")),
     195        2194 :     _tke_name(getParam<MooseFunctorName>("tke_name")),
     196        4388 :     _tked_name(getParam<MooseFunctorName>("tked_name"))
     197             : {
     198        1097 :   if (_verbose && _turbulence_model != "none")
     199           6 :     _console << "Creating a " << std::string(_turbulence_model) << " turbulence model."
     200           2 :              << std::endl;
     201             : 
     202             :   // Keep track of the variable names, for loading variables from files notably
     203        1097 :   if (_turbulence_model == "mixing-length")
     204          47 :     saveAuxVariableName(_mixing_length_name);
     205        1050 :   else if (_turbulence_model == "k-epsilon")
     206             :   {
     207         122 :     saveSolverVariableName(_tke_name);
     208         122 :     saveSolverVariableName(_tked_name);
     209         244 :     if (getParam<bool>("mu_t_as_aux_variable"))
     210          84 :       saveAuxVariableName(_turbulent_viscosity_name);
     211         244 :     if (getParam<bool>("k_t_as_aux_variable"))
     212          19 :       saveAuxVariableName(NS::k_t);
     213             :   }
     214             : 
     215             :   // Parameter checks
     216        1097 :   if (_turbulence_model == "none")
     217        1856 :     errorInconsistentDependentParameter("turbulence_handling", "none", {"turbulence_walls"});
     218        1097 :   if (_turbulence_model != "mixing-length")
     219        2100 :     errorDependentParameter("turbulence_handling",
     220             :                             "mixing-length",
     221             :                             {"mixing_length_delta",
     222             :                              "mixing_length_aux_execute_on",
     223             :                              "von_karman_const",
     224             :                              "von_karman_const_0",
     225             :                              "mixing_length_two_term_bc_expansion"});
     226        1097 :   if (_turbulence_model != "k-epsilon")
     227             :   {
     228        1950 :     errorDependentParameter("turbulence_handling",
     229             :                             "k-epsilon",
     230             :                             {"C_mu",
     231             :                              "C1_eps",
     232             :                              "C2_eps",
     233             :                              "bulk_wall_treatment",
     234             :                              "tke_scaling",
     235             :                              "tke_face_interpolation",
     236             :                              "tke_two_term_bc_expansion",
     237             :                              "tked_scaling",
     238             :                              "tked_face_interpolation",
     239             :                              "tked_two_term_bc_expansion",
     240             :                              "turbulent_viscosity_two_term_bc_expansion"});
     241        1950 :     checkSecondParamSetOnlyIfFirstOneTrue("mu_t_as_aux_variable", "initial_mu_t");
     242             :   }
     243        1097 : }
     244             : 
     245             : void
     246        1097 : WCNSFVTurbulencePhysics::initializePhysicsAdditional()
     247             : {
     248        1097 :   if (_turbulence_model == "k-epsilon")
     249         122 :     getProblem().needSolutionState(2, Moose::SolutionIterationType::Nonlinear);
     250        1097 : }
     251             : 
     252             : void
     253       12988 : WCNSFVTurbulencePhysics::actOnAdditionalTasks()
     254             : {
     255             :   // Other Physics may not exist or be initialized at construction time, so
     256             :   // we retrieve them now, on this task which occurs after 'init_physics'
     257       12988 :   if (_current_task == "get_turbulence_physics")
     258        1089 :     retrieveCoupledPhysics();
     259       12988 : }
     260             : 
     261             : void
     262        1089 : WCNSFVTurbulencePhysics::retrieveCoupledPhysics()
     263             : {
     264             :   // _flow_equations_physics is initialized by 'WCNSFVCoupledAdvectionPhysicsHelper'
     265        1089 :   if (_flow_equations_physics && _flow_equations_physics->hasFlowEquations())
     266        1066 :     _has_flow_equations = true;
     267             :   else
     268          23 :     _has_flow_equations = false;
     269             : 
     270             :   // Sanity check for interaction for fluid heat transfer physics
     271        3267 :   if (isParamValid("fluid_heat_transfer_physics") && _turbulence_model != "none")
     272             :   {
     273         338 :     _fluid_energy_physics = getCoupledPhysics<WCNSFVFluidHeatTransferPhysics>(
     274             :         getParam<PhysicsName>("fluid_heat_transfer_physics"), true);
     275             :     // Check for a missing parameter / do not support isolated physics for now
     276         207 :     if (!_fluid_energy_physics &&
     277         207 :         !getCoupledPhysics<const WCNSFVFluidHeatTransferPhysics>(true).empty())
     278           0 :       paramError("fluid_heat_transfer_physics",
     279             :                  "We currently do not support creating both turbulence physics and fluid heat "
     280             :                  "transfer physics that are not coupled together. Use "
     281             :                  "'fluid_heat_transfer_physics' to explicitly specify the coupling");
     282         169 :     if (_fluid_energy_physics && _fluid_energy_physics->hasEnergyEquation())
     283         110 :       _has_energy_equation = true;
     284             :     else
     285          59 :       _has_energy_equation = false;
     286             :   }
     287             :   else
     288             :   {
     289         920 :     _has_energy_equation = false;
     290         920 :     _fluid_energy_physics = nullptr;
     291             :   }
     292             : 
     293             :   // Sanity check for interaction with scalar transport physics
     294        3267 :   if (isParamValid("scalar_transport_physics") && _turbulence_model != "none")
     295             :   {
     296         338 :     _scalar_transport_physics = getCoupledPhysics<WCNSFVScalarTransportPhysics>(
     297             :         getParam<PhysicsName>("scalar_transport_physics"), true);
     298         223 :     if (!_scalar_transport_physics &&
     299         223 :         !getCoupledPhysics<const WCNSFVScalarTransportPhysics>(true).empty())
     300           0 :       paramError(
     301             :           "scalar_transport_physics",
     302             :           "We currently do not support creating both turbulence physics and scalar transport "
     303             :           "physics that are not coupled together");
     304         169 :     if (_scalar_transport_physics && _scalar_transport_physics->hasScalarEquations())
     305         100 :       _has_scalar_equations = true;
     306             :     else
     307          69 :       _has_scalar_equations = false;
     308             :   }
     309             :   else
     310             :   {
     311         920 :     _has_scalar_equations = false;
     312         920 :     _scalar_transport_physics = nullptr;
     313             :   }
     314             : 
     315             :   // To help remediate the danger of the parameter setup
     316        1089 :   if (_verbose)
     317             :   {
     318           2 :     if (_has_energy_equation)
     319           4 :       mooseInfoRepeated("Coupling turbulence physics with fluid heat transfer physics " +
     320           2 :                         _fluid_energy_physics->name());
     321             :     else
     322             :       mooseInfoRepeated("No fluid heat transfer equation considered by this turbulence "
     323             :                         "physics.");
     324           2 :     if (_has_scalar_equations)
     325           4 :       mooseInfoRepeated("Coupling turbulence physics with scalar transport physics " +
     326           2 :                         _scalar_transport_physics->name());
     327             :     else
     328             :       mooseInfoRepeated("No scalar transport equations considered by this turbulence physics.");
     329             :   }
     330        1089 : }
     331             : 
     332             : void
     333        1089 : WCNSFVTurbulencePhysics::addSolverVariables()
     334             : {
     335        1089 :   if (_turbulence_model == "mixing-length" || _turbulence_model == "none")
     336         967 :     return;
     337         122 :   else if (_turbulence_model == "k-epsilon")
     338             :   {
     339             :     // Dont add if the user already defined the variable
     340             :     // Add turbulent kinetic energy variable
     341         122 :     if (!shouldCreateVariable(_tke_name, _blocks, /*error if aux*/ true))
     342           0 :       reportPotentiallyMissedParameters(
     343             :           {"system_names", "tke_scaling", "tke_face_interpolation", "tke_two_term_bc_expansion"},
     344             :           "INSFVEnergyVariable");
     345         122 :     else if (_define_variables)
     346             :     {
     347         122 :       auto params = getFactory().getValidParams("INSFVEnergyVariable");
     348         122 :       assignBlocks(params, _blocks);
     349         366 :       params.set<std::vector<Real>>("scaling") = {getParam<Real>("tke_scaling")};
     350         366 :       params.set<MooseEnum>("face_interp_method") = getParam<MooseEnum>("tke_face_interpolation");
     351         244 :       params.set<bool>("two_term_boundary_expansion") = getParam<bool>("tke_two_term_bc_expansion");
     352         244 :       params.set<SolverSystemName>("solver_sys") = getSolverSystem(_tke_name);
     353             : 
     354         122 :       getProblem().addVariable("INSFVEnergyVariable", _tke_name, params);
     355         122 :     }
     356             :     else
     357           0 :       paramError("turbulence_kinetic_energy_variable",
     358           0 :                  "Variable (" + _tke_name +
     359             :                      ") supplied to the WCNSFVTurbulencePhysics does not exist!");
     360             : 
     361             :     // Add turbulent kinetic energy dissipation variable
     362         122 :     if (!shouldCreateVariable(_tked_name, _blocks, /*error if aux*/ true))
     363           0 :       reportPotentiallyMissedParameters(
     364             :           {"system_names", "tked_scaling", "tked_face_interpolation", "tked_two_term_bc_expansion"},
     365             :           "INSFVEnergyVariable");
     366         122 :     else if (_define_variables)
     367             :     {
     368         122 :       auto params = getFactory().getValidParams("INSFVEnergyVariable");
     369         122 :       assignBlocks(params, _blocks);
     370         366 :       params.set<std::vector<Real>>("scaling") = {getParam<Real>("tked_scaling")};
     371         366 :       params.set<MooseEnum>("face_interp_method") = getParam<MooseEnum>("tked_face_interpolation");
     372         122 :       params.set<bool>("two_term_boundary_expansion") =
     373         244 :           getParam<bool>("tked_two_term_bc_expansion");
     374         244 :       params.set<SolverSystemName>("solver_sys") = getSolverSystem(_tked_name);
     375         122 :       getProblem().addVariable("INSFVEnergyVariable", _tked_name, params);
     376         122 :     }
     377             :     else
     378           0 :       paramError("turbulence_kinetic_energy_dissipation_variable",
     379           0 :                  "Variable (" + _tked_name +
     380             :                      ") supplied to the WCNSFVTurbulencePhysics does not exist!");
     381             :   }
     382             : }
     383             : 
     384             : void
     385        1097 : WCNSFVTurbulencePhysics::addAuxiliaryVariables()
     386             : {
     387        1097 :   if (_turbulence_model == "mixing-length" && _define_variables)
     388             :   {
     389          47 :     auto params = getFactory().getValidParams("MooseVariableFVReal");
     390          47 :     assignBlocks(params, _blocks);
     391          94 :     if (isParamValid("mixing_length_two_term_bc_expansion"))
     392          47 :       params.set<bool>("two_term_boundary_expansion") =
     393         141 :           getParam<bool>("mixing_length_two_term_bc_expansion");
     394          47 :     if (!shouldCreateVariable(_tke_name, _blocks, /*error if aux*/ false))
     395           0 :       reportPotentiallyMissedParameters({"mixing_length_two_term_bc_expansion"},
     396             :                                         "MooseVariableFVReal");
     397             :     else
     398          94 :       getProblem().addAuxVariable("MooseVariableFVReal", _mixing_length_name, params);
     399          47 :   }
     400        1341 :   if (_turbulence_model == "k-epsilon" && getParam<bool>("mu_t_as_aux_variable"))
     401             :   {
     402          84 :     auto params = getFactory().getValidParams("MooseVariableFVReal");
     403          84 :     assignBlocks(params, _blocks);
     404         168 :     if (isParamValid("turbulent_viscosity_two_term_bc_expansion"))
     405          84 :       params.set<bool>("two_term_boundary_expansion") =
     406         252 :           getParam<bool>("turbulent_viscosity_two_term_bc_expansion");
     407          84 :     if (!shouldCreateVariable(_turbulent_viscosity_name, _blocks, /*error if aux*/ false))
     408           0 :       reportPotentiallyMissedParameters({"turbulent_viscosity_two_term_bc_expansion"},
     409             :                                         "MooseVariableFVReal");
     410             :     else
     411         168 :       getProblem().addAuxVariable("MooseVariableFVReal", _turbulent_viscosity_name, params);
     412          84 :   }
     413        1341 :   if (_turbulence_model == "k-epsilon" && getParam<bool>("k_t_as_aux_variable"))
     414             :   {
     415          19 :     auto params = getFactory().getValidParams("MooseVariableFVReal");
     416          19 :     assignBlocks(params, _blocks);
     417          38 :     if (shouldCreateVariable(NS::k_t, _blocks, /*error if aux*/ false))
     418          38 :       getProblem().addAuxVariable("MooseVariableFVReal", NS::k_t, params);
     419          19 :   }
     420        1097 : }
     421             : 
     422             : void
     423        1069 : WCNSFVTurbulencePhysics::addFVKernels()
     424             : {
     425        1069 :   if (_turbulence_model == "none")
     426             :     return;
     427             : 
     428             :   // Turbulence terms in other equations
     429         169 :   if (_has_flow_equations)
     430         169 :     addFlowTurbulenceKernels();
     431         169 :   if (_has_energy_equation)
     432         110 :     addFluidEnergyTurbulenceKernels();
     433         169 :   if (_has_scalar_equations)
     434         100 :     addScalarAdvectionTurbulenceKernels();
     435             : 
     436             :   // Turbulence models with their own set of equations
     437         167 :   if (_turbulence_model == "k-epsilon")
     438             :   {
     439         122 :     if (isTransient())
     440           0 :       addKEpsilonTimeDerivatives();
     441         122 :     addKEpsilonAdvection();
     442         122 :     addKEpsilonDiffusion();
     443         122 :     addKEpsilonSink();
     444             :   }
     445             : }
     446             : 
     447             : void
     448         169 : WCNSFVTurbulencePhysics::addFlowTurbulenceKernels()
     449             : {
     450         169 :   if (_turbulence_model == "mixing-length")
     451             :   {
     452         188 :     const std::string u_names[3] = {"u", "v", "w"};
     453          47 :     const std::string kernel_type = "INSFVMixingLengthReynoldsStress";
     454          47 :     InputParameters params = getFactory().getValidParams(kernel_type);
     455          47 :     assignBlocks(params, _blocks);
     456          47 :     params.set<MooseFunctorName>(NS::density) = _density_name;
     457          47 :     params.set<MooseFunctorName>(NS::mixing_length) = _mixing_length_name;
     458             : 
     459          47 :     std::string kernel_name = prefix() + "ins_momentum_mixing_length_reynolds_stress_";
     460          47 :     if (_porous_medium_treatment)
     461           0 :       kernel_name = prefix() + "pins_momentum_mixing_length_reynolds_stress_";
     462             : 
     463          94 :     params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName();
     464         141 :     for (const auto dim_i : make_range(dimension()))
     465         188 :       params.set<MooseFunctorName>(u_names[dim_i]) = _velocity_names[dim_i];
     466             : 
     467         141 :     for (const auto d : make_range(dimension()))
     468             :     {
     469         188 :       params.set<NonlinearVariableName>("variable") = _velocity_names[d];
     470         188 :       params.set<MooseEnum>("momentum_component") = NS::directions[d];
     471             : 
     472         188 :       getProblem().addFVKernel(kernel_type, kernel_name + NS::directions[d], params);
     473             :     }
     474         235 :   }
     475         122 :   else if (_turbulence_model == "k-epsilon")
     476             :   {
     477             :     // We rely on using the turbulent viscosity in the flow equation
     478             :     // This check is rudimentary, we should think of a better way
     479             :     // We could also check for the use of 'mu_t' with the right parameters already
     480         244 :     if (_flow_equations_physics->dynamicViscosityName() != "mu" &&
     481         122 :         !MooseUtils::isFloat(_flow_equations_physics->dynamicViscosityName()))
     482           0 :       mooseError(
     483             :           "Regular fluid viscosity 'mu' should be used for the momentum diffusion term. You are "
     484           0 :           "currently using: " +
     485           0 :           _flow_equations_physics->dynamicViscosityName());
     486             : 
     487         488 :     const std::string u_names[3] = {"u", "v", "w"};
     488         122 :     const std::string kernel_type = "INSFVMomentumDiffusion";
     489         122 :     InputParameters params = getFactory().getValidParams(kernel_type);
     490         122 :     assignBlocks(params, _blocks);
     491         244 :     params.set<MooseFunctorName>("mu") = _turbulent_viscosity_name;
     492         244 :     params.set<MooseEnum>("mu_interp_method") =
     493         244 :         getParam<MooseEnum>("turbulent_viscosity_interp_method");
     494         122 :     params.set<MooseEnum>("variable_interp_method") =
     495         244 :         _flow_equations_physics->getMomentumFaceInterpolationMethod();
     496         122 :     params.set<bool>("complete_expansion") = true;
     497             : 
     498         122 :     std::string kernel_name = prefix() + "ins_momentum_k_epsilon_reynolds_stress_";
     499         122 :     if (_porous_medium_treatment)
     500           0 :       kernel_name = prefix() + "pins_momentum_k_epsilon_reynolds_stress_";
     501             : 
     502         244 :     params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName();
     503         366 :     for (const auto dim_i : make_range(dimension()))
     504         488 :       params.set<MooseFunctorName>(u_names[dim_i]) = _velocity_names[dim_i];
     505             : 
     506         366 :     for (const auto d : make_range(dimension()))
     507             :     {
     508         488 :       params.set<NonlinearVariableName>("variable") = _velocity_names[d];
     509         488 :       params.set<MooseEnum>("momentum_component") = NS::directions[d];
     510             : 
     511         488 :       getProblem().addFVKernel(kernel_type, kernel_name + NS::directions[d], params);
     512             :     }
     513         610 :   }
     514         169 : }
     515             : 
     516             : void
     517         110 : WCNSFVTurbulencePhysics::addFluidEnergyTurbulenceKernels()
     518             : {
     519         110 :   if (_turbulence_model == "mixing-length")
     520             :   {
     521          28 :     const std::string u_names[3] = {"u", "v", "w"};
     522           7 :     const std::string kernel_type = "WCNSFVMixingLengthEnergyDiffusion";
     523           7 :     InputParameters params = getFactory().getValidParams(kernel_type);
     524           7 :     assignBlocks(params, _blocks);
     525           7 :     params.set<MooseFunctorName>(NS::density) = _density_name;
     526           7 :     params.set<MooseFunctorName>(NS::cp) = _fluid_energy_physics->getSpecificHeatName();
     527           7 :     params.set<MooseFunctorName>(NS::mixing_length) = _mixing_length_name;
     528          14 :     params.set<Real>("schmidt_number") = getParam<Real>("turbulent_prandtl");
     529           7 :     params.set<NonlinearVariableName>("variable") =
     530           7 :         _flow_equations_physics->getFluidTemperatureName();
     531             : 
     532          28 :     for (const auto dim_i : make_range(dimension()))
     533          28 :       params.set<MooseFunctorName>(u_names[dim_i]) = _velocity_names[dim_i];
     534             : 
     535           7 :     if (_porous_medium_treatment)
     536           0 :       getProblem().addFVKernel(
     537           0 :           kernel_type, prefix() + "pins_energy_mixing_length_diffusion", params);
     538             :     else
     539           7 :       getProblem().addFVKernel(
     540          14 :           kernel_type, prefix() + "ins_energy_mixing_length_diffusion", params);
     541          35 :   }
     542         103 :   else if (_turbulence_model == "k-epsilon")
     543             :   {
     544         103 :     const std::string kernel_type = "FVDiffusion";
     545         103 :     const auto T_fluid_name = _flow_equations_physics->getFluidTemperatureName();
     546         103 :     InputParameters params = getFactory().getValidParams(kernel_type);
     547         103 :     assignBlocks(params, _blocks);
     548         206 :     params.set<NonlinearVariableName>("variable") = T_fluid_name;
     549         206 :     params.set<MooseFunctorName>("coeff") = NS::k_t;
     550         206 :     getProblem().addFVKernel(kernel_type, prefix() + T_fluid_name + "_turbulent_diffusion", params);
     551         103 :   }
     552         110 : }
     553             : 
     554             : void
     555         100 : WCNSFVTurbulencePhysics::addScalarAdvectionTurbulenceKernels()
     556             : {
     557         100 :   const auto & passive_scalar_names = _scalar_transport_physics->getAdvectedScalarNames();
     558         200 :   const auto & passive_scalar_schmidt_number = getParam<std::vector<Real>>("Sc_t");
     559         100 :   if (passive_scalar_schmidt_number.size() != passive_scalar_names.size() &&
     560             :       passive_scalar_schmidt_number.size() != 1)
     561           2 :     paramError(
     562             :         "Sc_t",
     563             :         "The number of turbulent Schmidt numbers defined is not equal to the number of passive "
     564             :         "scalar fields!");
     565             : 
     566          98 :   if (_turbulence_model == "mixing-length")
     567             :   {
     568          88 :     const std::string u_names[3] = {"u", "v", "w"};
     569          22 :     const std::string kernel_type = "INSFVMixingLengthScalarDiffusion";
     570          22 :     InputParameters params = getFactory().getValidParams(kernel_type);
     571          22 :     assignBlocks(params, _blocks);
     572          22 :     params.set<MooseFunctorName>(NS::mixing_length) = _mixing_length_name;
     573          88 :     for (const auto dim_i : make_range(dimension()))
     574          88 :       params.set<MooseFunctorName>(u_names[dim_i]) = _velocity_names[dim_i];
     575             : 
     576          44 :     for (const auto & name_i : index_range(passive_scalar_names))
     577             :     {
     578          44 :       params.set<NonlinearVariableName>("variable") = passive_scalar_names[name_i];
     579          22 :       if (passive_scalar_schmidt_number.size() > 1)
     580           0 :         params.set<Real>("schmidt_number") = passive_scalar_schmidt_number[name_i];
     581          22 :       else if (passive_scalar_schmidt_number.size() == 1)
     582          22 :         params.set<Real>("schmidt_number") = passive_scalar_schmidt_number[0];
     583             :       else
     584           0 :         params.set<Real>("schmidt_number") = 1.0;
     585             : 
     586          44 :       getProblem().addFVKernel(
     587          44 :           kernel_type, prefix() + passive_scalar_names[name_i] + "_mixing_length", params);
     588             :     }
     589         110 :   }
     590          76 :   else if (_turbulence_model == "k-epsilon")
     591             :   {
     592          76 :     const std::string kernel_type = "FVDiffusion";
     593          76 :     InputParameters params = getFactory().getValidParams(kernel_type);
     594          76 :     assignBlocks(params, _blocks);
     595             : 
     596         228 :     for (const auto & name_i : index_range(passive_scalar_names))
     597             :     {
     598         304 :       params.set<NonlinearVariableName>("variable") = passive_scalar_names[name_i];
     599         304 :       params.set<MooseFunctorName>("coeff") = NS::mu_t_passive_scalar;
     600         304 :       getProblem().addFVKernel(
     601         304 :           kernel_type, prefix() + passive_scalar_names[name_i] + "_turbulent_diffusion", params);
     602             :     }
     603          76 :   }
     604          98 : }
     605             : 
     606             : void
     607           0 : WCNSFVTurbulencePhysics::addKEpsilonTimeDerivatives()
     608             : {
     609           0 :   const std::string kernel_type = "FVFunctorTimeKernel";
     610           0 :   InputParameters params = getFactory().getValidParams(kernel_type);
     611           0 :   assignBlocks(params, _blocks);
     612             : 
     613           0 :   params.set<NonlinearVariableName>("variable") = _tke_name;
     614           0 :   if (shouldCreateTimeDerivative(_tke_name, _blocks, /*error if already defined*/ false))
     615           0 :     getProblem().addFVKernel(kernel_type, prefix() + "tke_time", params);
     616           0 :   params.set<NonlinearVariableName>("variable") = _tked_name;
     617           0 :   if (shouldCreateTimeDerivative(_tked_name, _blocks, /*error if already defined*/ false))
     618           0 :     getProblem().addFVKernel(kernel_type, prefix() + "tked_time", params);
     619           0 : }
     620             : 
     621             : void
     622         122 : WCNSFVTurbulencePhysics::addKEpsilonAdvection()
     623             : {
     624         122 :   const std::string kernel_type = "INSFVTurbulentAdvection";
     625         122 :   InputParameters params = getFactory().getValidParams(kernel_type);
     626             : 
     627         122 :   assignBlocks(params, _blocks);
     628             : 
     629         122 :   params.set<MooseEnum>("velocity_interp_method") = _velocity_interpolation;
     630         244 :   params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName();
     631         122 :   params.set<MooseFunctorName>(NS::density) = _flow_equations_physics->densityName();
     632         122 :   params.set<bool>("neglect_advection_derivatives") =
     633         244 :       getParam<bool>("neglect_advection_derivatives");
     634             : 
     635         244 :   params.set<MooseEnum>("advected_interp_method") =
     636         244 :       getParam<MooseEnum>("tke_advection_interpolation");
     637         244 :   params.set<NonlinearVariableName>("variable") = _tke_name;
     638         244 :   getProblem().addFVKernel(kernel_type, prefix() + "tke_advection", params);
     639         244 :   params.set<NonlinearVariableName>("variable") = _tked_name;
     640         122 :   params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     641         244 :   params.set<MooseEnum>("advected_interp_method") =
     642         366 :       getParam<MooseEnum>("tked_advection_interpolation");
     643         244 :   getProblem().addFVKernel(kernel_type, prefix() + "tked_advection", params);
     644         244 : }
     645             : 
     646             : void
     647         122 : WCNSFVTurbulencePhysics::addKEpsilonDiffusion()
     648             : {
     649             :   {
     650         122 :     const std::string kernel_type = "INSFVTurbulentDiffusion";
     651         122 :     InputParameters params = getFactory().getValidParams(kernel_type);
     652         122 :     assignBlocks(params, _blocks);
     653             : 
     654         244 :     params.set<NonlinearVariableName>("variable") = _tke_name;
     655         244 :     params.set<MooseFunctorName>("coeff") = _flow_equations_physics->dynamicViscosityName();
     656         244 :     getProblem().addFVKernel(kernel_type, prefix() + "tke_diffusion_mu", params);
     657             : 
     658         122 :     params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     659         244 :     params.set<NonlinearVariableName>("variable") = _tked_name;
     660         244 :     getProblem().addFVKernel(kernel_type, prefix() + "tked_diffusion_mu", params);
     661         122 :   }
     662             : 
     663             :   {
     664         122 :     const std::string kernel_type = "INSFVTurbulentDiffusion";
     665         122 :     InputParameters params = getFactory().getValidParams(kernel_type);
     666         122 :     assignBlocks(params, _blocks);
     667             : 
     668         244 :     params.set<NonlinearVariableName>("variable") = _tke_name;
     669         244 :     params.set<MooseFunctorName>("coeff") = _turbulent_viscosity_name;
     670         366 :     params.set<MooseFunctorName>("scaling_coef") = getParam<MooseFunctorName>("sigma_k");
     671         244 :     params.set<MooseEnum>("coeff_interp_method") =
     672         366 :         getParam<MooseEnum>("turbulent_viscosity_interp_method");
     673         244 :     getProblem().addFVKernel(kernel_type, prefix() + "tke_diffusion_mu_turb", params);
     674             : 
     675         244 :     params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     676         244 :     params.set<NonlinearVariableName>("variable") = _tked_name;
     677         366 :     params.set<MooseFunctorName>("scaling_coef") = getParam<MooseFunctorName>("sigma_eps");
     678         244 :     getProblem().addFVKernel(kernel_type, prefix() + "tked_diffusion_mu_turb", params);
     679         122 :   }
     680         122 : }
     681             : 
     682             : void
     683         122 : WCNSFVTurbulencePhysics::addKEpsilonSink()
     684             : {
     685         488 :   const std::string u_names[3] = {"u", "v", "w"};
     686             :   {
     687         122 :     const std::string kernel_type = "INSFVTKESourceSink";
     688         122 :     InputParameters params = getFactory().getValidParams(kernel_type);
     689         122 :     assignBlocks(params, _blocks);
     690         244 :     params.set<NonlinearVariableName>("variable") = _tke_name;
     691         122 :     params.set<MooseFunctorName>(NS::TKED) = _tked_name;
     692         122 :     params.set<MooseFunctorName>(NS::density) = _flow_equations_physics->densityName();
     693         122 :     params.set<MooseFunctorName>(NS::mu) = _flow_equations_physics->dynamicViscosityName();
     694         122 :     params.set<MooseFunctorName>(NS::mu_t) = _turbulent_viscosity_name;
     695         244 :     params.set<Real>("C_pl") = getParam<Real>("C_pl");
     696         244 :     params.set<bool>("linearized_model") = getParam<bool>("linearize_sink_sources");
     697         122 :     params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     698         122 :     params.set<MooseEnum>("wall_treatment") = _wall_treatment_eps;
     699             :     // Currently only Newton method for WCNSFVTurbulencePhysics
     700         122 :     params.set<bool>("newton_solve") = true;
     701         488 :     for (const auto d : make_range(dimension()))
     702         488 :       params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
     703         244 :     getProblem().addFVKernel(kernel_type, prefix() + "tke_source_sink", params);
     704         122 :   }
     705             : 
     706             :   {
     707         122 :     const std::string kernel_type = "INSFVTKEDSourceSink";
     708         122 :     InputParameters params = getFactory().getValidParams(kernel_type);
     709         122 :     assignBlocks(params, _blocks);
     710         244 :     params.set<NonlinearVariableName>("variable") = _tked_name;
     711         122 :     params.set<MooseFunctorName>(NS::TKE) = _tke_name;
     712         122 :     params.set<MooseFunctorName>(NS::density) = _flow_equations_physics->densityName();
     713         122 :     params.set<MooseFunctorName>(NS::mu) = _flow_equations_physics->dynamicViscosityName();
     714         122 :     params.set<MooseFunctorName>(NS::mu_t) = _turbulent_viscosity_name;
     715         244 :     params.set<Real>("C_pl") = getParam<Real>("C_pl");
     716         244 :     params.set<bool>("linearized_model") = getParam<bool>("linearize_sink_sources");
     717         122 :     params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     718         122 :     params.set<MooseEnum>("wall_treatment") = _wall_treatment_eps;
     719         244 :     params.set<Real>("C1_eps") = getParam<Real>("C1_eps");
     720         244 :     params.set<Real>("C2_eps") = getParam<Real>("C2_eps");
     721             :     // Currently only Newton method for WCNSFVTurbulencePhysics
     722         122 :     params.set<bool>("newton_solve") = true;
     723         488 :     for (const auto d : make_range(dimension()))
     724         488 :       params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
     725         244 :     getProblem().addFVKernel(kernel_type, prefix() + "tked_source_sink", params);
     726         122 :   }
     727         610 : }
     728             : 
     729             : void
     730        1075 : WCNSFVTurbulencePhysics::addAuxiliaryKernels()
     731             : {
     732             :   // Note that if we are restarting this will overwrite the restarted mixing-length
     733        1075 :   if (_turbulence_model == "mixing-length")
     734             :   {
     735          47 :     const std::string ml_kernel_type = "WallDistanceMixingLengthAux";
     736          47 :     InputParameters ml_params = getFactory().getValidParams(ml_kernel_type);
     737          47 :     assignBlocks(ml_params, _blocks);
     738          94 :     ml_params.set<AuxVariableName>("variable") = _mixing_length_name;
     739          94 :     ml_params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     740          94 :     if (parameters().isParamValid("mixing_length_aux_execute_on"))
     741          74 :       ml_params.set<ExecFlagEnum>("execute_on") =
     742          74 :           getParam<ExecFlagEnum>("mixing_length_aux_execute_on");
     743             :     else
     744          40 :       ml_params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
     745          94 :     ml_params.set<MooseFunctorName>("von_karman_const") =
     746          47 :         getParam<MooseFunctorName>("von_karman_const");
     747          94 :     ml_params.set<MooseFunctorName>("von_karman_const_0") =
     748          47 :         getParam<MooseFunctorName>("von_karman_const_0");
     749         141 :     ml_params.set<MooseFunctorName>("delta") = getParam<MooseFunctorName>("mixing_length_delta");
     750             : 
     751          94 :     getProblem().addAuxKernel(ml_kernel_type, prefix() + "mixing_length_aux ", ml_params);
     752          47 :   }
     753             : 
     754        1319 :   if (_turbulence_model == "k-epsilon" && getParam<bool>("mu_t_as_aux_variable"))
     755             :   {
     756         336 :     const std::string u_names[3] = {"u", "v", "w"};
     757          84 :     const std::string mut_kernel_type = "kEpsilonViscosityAux";
     758          84 :     InputParameters params = getFactory().getValidParams(mut_kernel_type);
     759          84 :     assignBlocks(params, _blocks);
     760         168 :     params.set<AuxVariableName>("variable") = _turbulent_viscosity_name;
     761         336 :     for (const auto d : make_range(dimension()))
     762         336 :       params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
     763          84 :     params.set<MooseFunctorName>(NS::TKE) = _tke_name;
     764          84 :     params.set<MooseFunctorName>(NS::TKED) = _tked_name;
     765          84 :     params.set<MooseFunctorName>(NS::density) = _flow_equations_physics->densityName();
     766          84 :     params.set<MooseFunctorName>(NS::mu) = _flow_equations_physics->dynamicViscosityName();
     767         168 :     params.set<Real>("C_mu") = getParam<Real>("C_mu");
     768          84 :     params.set<MooseEnum>("wall_treatment") = _wall_treatment_eps;
     769         168 :     params.set<bool>("bulk_wall_treatment") = getParam<bool>("bulk_wall_treatment");
     770          84 :     params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     771         252 :     params.set<ExecFlagEnum>("execute_on") = {EXEC_NONLINEAR};
     772          84 :     params.set<bool>("newton_solve") = true;
     773         168 :     getProblem().addAuxKernel(mut_kernel_type, prefix() + "mixing_length_aux ", params);
     774         420 :   }
     775        1338 :   if (_turbulence_model == "k-epsilon" && getParam<bool>("k_t_as_aux_variable") &&
     776          19 :       _has_energy_equation)
     777             :   {
     778          19 :     const std::string kt_kernel_type = "TurbulentConductivityAux";
     779          19 :     InputParameters params = getFactory().getValidParams(kt_kernel_type);
     780          19 :     assignBlocks(params, _blocks);
     781          38 :     params.set<AuxVariableName>("variable") = NS::k_t;
     782          19 :     params.set<MooseFunctorName>(NS::cp) = _fluid_energy_physics->getSpecificHeatName();
     783          19 :     params.set<MooseFunctorName>(NS::mu_t) = _turbulent_viscosity_name;
     784          38 :     params.set<MooseFunctorName>(NS::turbulent_Prandtl) = getParam<MooseFunctorName>("Pr_t");
     785          76 :     params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_NONLINEAR};
     786          38 :     getProblem().addAuxKernel(kt_kernel_type, prefix() + "turbulent_conductivity_aux ", params);
     787          19 :   }
     788        1188 : }
     789             : 
     790             : void
     791        1061 : WCNSFVTurbulencePhysics::addFVBCs()
     792             : {
     793        4244 :   const std::string u_names[3] = {"u", "v", "w"};
     794             : 
     795        1305 :   if (_turbulence_model == "k-epsilon" && getParam<bool>("mu_t_as_aux_variable"))
     796             :   {
     797             :     mooseAssert(_flow_equations_physics, "Should have a flow equation physics");
     798          84 :     const std::string bc_type = "INSFVTurbulentViscosityWallFunction";
     799          84 :     InputParameters params = getFactory().getValidParams(bc_type);
     800          84 :     params.set<std::vector<BoundaryName>>("boundary") = _turbulence_walls;
     801         168 :     params.set<NonlinearVariableName>("variable") = _turbulent_viscosity_name;
     802          84 :     params.set<MooseFunctorName>(NS::density) = _flow_equations_physics->densityName();
     803          84 :     params.set<MooseFunctorName>(NS::mu) = _flow_equations_physics->dynamicViscosityName();
     804          84 :     params.set<MooseFunctorName>(NS::mu_t) = _turbulent_viscosity_name;
     805          84 :     params.set<MooseFunctorName>(NS::TKE) = _tke_name;
     806          84 :     params.set<MooseEnum>("wall_treatment") = _wall_treatment_eps;
     807         336 :     for (const auto d : make_range(dimension()))
     808         336 :       params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
     809             : 
     810         168 :     getProblem().addFVBC(bc_type, prefix() + "turbulence_walls", params);
     811             :     // Energy wall function boundary conditions are added in the WCNSFVFluidEnergyPhysics
     812             :     // because it facilitates counting the number of walls, specifying energy wall functors
     813             :     // the same way as for boundary conditions
     814          84 :   }
     815        5305 : }
     816             : 
     817             : void
     818        1075 : WCNSFVTurbulencePhysics::addInitialConditions()
     819             : {
     820        1075 :   if (_turbulence_model == "mixing-length" || _turbulence_model == "none")
     821         953 :     return;
     822         122 :   const std::string ic_type = "FunctionIC";
     823         122 :   InputParameters params = getFactory().getValidParams(ic_type);
     824             : 
     825             :   // Parameter checking: error if initial conditions are provided but not going to be used
     826         366 :   if ((getParam<bool>("initialize_variables_from_mesh_file") || !_define_variables) &&
     827         198 :       ((getParam<bool>("mu_t_as_aux_variable") && isParamValid("initial_mu_t")) ||
     828         198 :        isParamSetByUser("initial_tke") || isParamSetByUser("initial_tked")))
     829           0 :     mooseError("inital_mu_t/tke/tked should not be provided if we are restarting from a mesh file "
     830             :                "or not defining variables in the Physics");
     831             : 
     832             :   // do not set initial conditions if we are not defining variables
     833         122 :   if (!_define_variables)
     834             :     return;
     835             :   // on regular restarts (from checkpoint), we obey the user specification of initial conditions
     836             : 
     837         244 :   if (getParam<bool>("mu_t_as_aux_variable"))
     838             :   {
     839          84 :     const auto rho_name = _flow_equations_physics->densityName();
     840             :     // If the user provided an initial value, we use that
     841         168 :     if (isParamValid("initial_mu_t"))
     842         252 :       params.set<FunctionName>("function") = getParam<FunctionName>("initial_mu_t");
     843             :     // If we can compute the initialization value from the user parameters, we do that
     844           0 :     else if (MooseUtils::isFloat(rho_name) &&
     845           0 :              MooseUtils::isFloat(getParam<FunctionName>("initial_tke")) &&
     846           0 :              MooseUtils::isFloat(getParam<FunctionName>("initial_tked")))
     847           0 :       params.set<FunctionName>("function") =
     848           0 :           std::to_string(std::atof(rho_name.c_str()) * getParam<Real>("C_mu") *
     849           0 :                          std::pow(std::atof(getParam<FunctionName>("initial_tke").c_str()), 2) /
     850           0 :                          std::atof(getParam<FunctionName>("initial_tked").c_str()));
     851             :     else
     852           0 :       paramError("initial_mu_t",
     853             :                  "Initial turbulent viscosity should be provided. A sensible value is "
     854             :                  "rho * C_mu TKE_initial^2 / TKED_initial");
     855             : 
     856          84 :     params.set<VariableName>("variable") = _turbulent_viscosity_name;
     857             :     // Always obey the user specification of an initial condition
     858         336 :     if (shouldCreateIC(_turbulent_viscosity_name,
     859          84 :                        _blocks,
     860         252 :                        /*whether IC is a default*/ !isParamSetByUser("initial_mu_t"),
     861         168 :                        /*error if already an IC*/ isParamSetByUser("initial_mu_t")))
     862         252 :       getProblem().addInitialCondition(ic_type, prefix() + "initial_mu_turb", params);
     863             :   }
     864          76 :   else if (isParamSetByUser("initial_mu_t"))
     865           0 :     paramError("initial_mu_t",
     866             :                "This parameter can only be specified if 'mu_t_as_aux_variable=true'");
     867             : 
     868         122 :   params.set<VariableName>("variable") = _tke_name;
     869         366 :   params.set<FunctionName>("function") = getParam<FunctionName>("initial_tke");
     870         488 :   if (shouldCreateIC(_tke_name,
     871         122 :                      _blocks,
     872         366 :                      /*whether IC is a default*/ !isParamSetByUser("initial_tke"),
     873         244 :                      /*error if already an IC*/ isParamSetByUser("initial_tke")))
     874         294 :     getProblem().addInitialCondition(ic_type, prefix() + "initial_tke", params);
     875         122 :   params.set<VariableName>("variable") = _tked_name;
     876         366 :   params.set<FunctionName>("function") = getParam<FunctionName>("initial_tked");
     877         366 :   if (shouldCreateIC(_tked_name,
     878             :                      _blocks,
     879         366 :                      /*whether IC is a default*/ !isParamSetByUser("initial_tked"),
     880         244 :                      /*error if already an IC*/ isParamSetByUser("initial_tked")))
     881         294 :     getProblem().addInitialCondition(ic_type, prefix() + "initial_tked", params);
     882         122 : }
     883             : 
     884             : void
     885        1075 : WCNSFVTurbulencePhysics::addMaterials()
     886             : {
     887        1075 :   if (_turbulence_model == "mixing-length")
     888             :   {
     889         188 :     const std::string u_names[3] = {"u", "v", "w"};
     890             :     InputParameters params =
     891          47 :         getFactory().getValidParams("MixingLengthTurbulentViscosityFunctorMaterial");
     892          47 :     assignBlocks(params, _blocks);
     893             : 
     894         188 :     for (const auto d : make_range(dimension()))
     895         188 :       params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
     896             : 
     897          47 :     params.set<MooseFunctorName>(NS::mixing_length) = _mixing_length_name;
     898          47 :     params.set<MooseFunctorName>(NS::density) = _density_name;
     899          47 :     params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
     900             : 
     901          94 :     getProblem().addMaterial("MixingLengthTurbulentViscosityFunctorMaterial",
     902          47 :                              prefix() + "mixing_length_material",
     903             :                              params);
     904         188 :   }
     905        1028 :   else if (_turbulence_model == "k-epsilon")
     906             :   {
     907         122 :     if (!getProblem().hasFunctor(NS::mu_eff, /*thread_id=*/0))
     908             :     {
     909         122 :       InputParameters params = getFactory().getValidParams("ADParsedFunctorMaterial");
     910         122 :       assignBlocks(params, _blocks);
     911         122 :       const auto mu_name = _flow_equations_physics->dynamicViscosityName();
     912             : 
     913             :       // Avoid defining floats as functors in the parsed expression
     914         122 :       if (!MooseUtils::isFloat(_turbulent_viscosity_name) && !MooseUtils::isFloat(mu_name))
     915           0 :         params.set<std::vector<std::string>>("functor_names") = {_turbulent_viscosity_name,
     916           0 :                                                                  mu_name};
     917         122 :       else if (MooseUtils::isFloat(_turbulent_viscosity_name) && !MooseUtils::isFloat(mu_name))
     918           0 :         params.set<std::vector<std::string>>("functor_names") = {mu_name};
     919         122 :       else if (!MooseUtils::isFloat(_turbulent_viscosity_name) && MooseUtils::isFloat(mu_name))
     920         366 :         params.set<std::vector<std::string>>("functor_names") = {_turbulent_viscosity_name};
     921             : 
     922         244 :       params.set<std::string>("expression") =
     923         244 :           _flow_equations_physics->dynamicViscosityName() + " + " + _turbulent_viscosity_name;
     924         244 :       params.set<std::string>("property_name") = NS::mu_eff;
     925         488 :       getProblem().addMaterial("ADParsedFunctorMaterial", prefix() + "effective_viscosity", params);
     926         122 :     }
     927         244 :     if (!getParam<bool>("mu_t_as_aux_variable"))
     928             :     {
     929          38 :       InputParameters params = getFactory().getValidParams("INSFVkEpsilonViscosityFunctorMaterial");
     930          38 :       params.set<MooseFunctorName>(NS::TKE) = _tke_name;
     931          38 :       params.set<MooseFunctorName>(NS::TKED) = _tked_name;
     932          38 :       params.set<MooseFunctorName>(NS::density) = _density_name;
     933         114 :       params.set<ExecFlagEnum>("execute_on") = {EXEC_NONLINEAR};
     934          76 :       if (getParam<bool>("output_mu_t"))
     935         114 :         params.set<std::vector<OutputName>>("outputs") = {"all"};
     936          76 :       getProblem().addMaterial(
     937          38 :           "INSFVkEpsilonViscosityFunctorMaterial", prefix() + "compute_mu_t", params);
     938          38 :     }
     939             : 
     940         122 :     if (_has_energy_equation && !getProblem().hasFunctor(NS::k_t, /*thread_id=*/0))
     941             :     {
     942             :       mooseAssert(!getParam<bool>("k_t_as_aux_variable"), "k_t should exist");
     943          84 :       InputParameters params = getFactory().getValidParams("ADParsedFunctorMaterial");
     944          84 :       assignBlocks(params, _blocks);
     945          84 :       const auto mu_t_name = NS::mu_t;
     946          84 :       const auto cp_name = _fluid_energy_physics->getSpecificHeatName();
     947          84 :       const auto Pr_t_name = getParam<MooseFunctorName>("Pr_t");
     948             : 
     949             :       // Avoid defining floats as functors in the parsed expression
     950          84 :       if (!MooseUtils::isFloat(cp_name) && !MooseUtils::isFloat(Pr_t_name))
     951           0 :         params.set<std::vector<std::string>>("functor_names") = {cp_name, Pr_t_name, mu_t_name};
     952          84 :       else if (MooseUtils::isFloat(cp_name) && !MooseUtils::isFloat(Pr_t_name))
     953           0 :         params.set<std::vector<std::string>>("functor_names") = {Pr_t_name, mu_t_name};
     954          84 :       else if (!MooseUtils::isFloat(cp_name) && MooseUtils::isFloat(Pr_t_name))
     955           0 :         params.set<std::vector<std::string>>("functor_names") = {cp_name, mu_t_name};
     956             :       else
     957         252 :         params.set<std::vector<std::string>>("functor_names") = {mu_t_name};
     958             : 
     959         252 :       params.set<std::string>("expression") = mu_t_name + "*" + cp_name + "/" + Pr_t_name;
     960          84 :       params.set<std::string>("property_name") = NS::k_t;
     961         252 :       params.set<ExecFlagEnum>("execute_on") = {EXEC_NONLINEAR};
     962         252 :       params.set<std::vector<OutputName>>("outputs") = {"all"};
     963         168 :       getProblem().addMaterial(
     964         168 :           "ADParsedFunctorMaterial", prefix() + "turbulent_heat_eff_conductivity", params);
     965          84 :     }
     966             : 
     967         122 :     if (_has_scalar_equations && !getProblem().hasFunctor(NS::mu_t_passive_scalar, /*thread_id=*/0))
     968             :     {
     969          76 :       InputParameters params = getFactory().getValidParams("ADParsedFunctorMaterial");
     970          76 :       assignBlocks(params, _blocks);
     971          76 :       const auto & rho_name = _flow_equations_physics->densityName();
     972             : 
     973             :       // Avoid defining floats as functors in the parsed expression
     974          76 :       if (!MooseUtils::isFloat(_turbulent_viscosity_name) && !MooseUtils::isFloat(rho_name))
     975           0 :         params.set<std::vector<std::string>>("functor_names") = {_turbulent_viscosity_name,
     976           0 :                                                                  rho_name};
     977          76 :       else if (MooseUtils::isFloat(_turbulent_viscosity_name) && !MooseUtils::isFloat(rho_name))
     978           0 :         params.set<std::vector<std::string>>("functor_names") = {rho_name};
     979          76 :       else if (!MooseUtils::isFloat(_turbulent_viscosity_name) && MooseUtils::isFloat(rho_name))
     980         228 :         params.set<std::vector<std::string>>("functor_names") = {_turbulent_viscosity_name};
     981             : 
     982         228 :       const auto turbulent_schmidt_number = getParam<std::vector<Real>>("Sc_t");
     983          76 :       if (turbulent_schmidt_number.size() != 1)
     984           0 :         paramError(
     985             :             "passive_scalar_schmidt_number",
     986             :             "Only one passive scalar turbulent Schmidt number can be specified with k-epsilon");
     987         304 :       params.set<std::string>("expression") = _turbulent_viscosity_name + "/" + rho_name + " / " +
     988         152 :                                               std::to_string(turbulent_schmidt_number[0]);
     989         152 :       params.set<std::string>("property_name") = NS::mu_t_passive_scalar;
     990         152 :       getProblem().addMaterial(
     991          76 :           "ADParsedFunctorMaterial", prefix() + "scalar_turbulent_diffusivity", params);
     992          76 :     }
     993             :   }
     994        1479 : }
     995             : 
     996             : unsigned short
     997        3219 : WCNSFVTurbulencePhysics::getNumberAlgebraicGhostingLayersNeeded() const
     998             : {
     999        3219 :   unsigned short ghost_layers = _flow_equations_physics->getNumberAlgebraicGhostingLayersNeeded();
    1000             :   // due to the computation of the eddy-diffusivity from the strain tensor
    1001        3219 :   if (_turbulence_model == "mixing-length")
    1002         274 :     ghost_layers = std::max(ghost_layers, (unsigned short)3);
    1003        3219 :   return ghost_layers;
    1004             : }

Generated by: LCOV version 1.14