LCOV - code coverage report
Current view: top level - src/physics - WCNSLinearFVTurbulencePhysics.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: #33416 (b10b36) with base 9fbd27 Lines: 169 197 85.8 %
Date: 2026-07-23 16:18:21 Functions: 12 14 85.7 %
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 "WCNSLinearFVTurbulencePhysics.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             : registerWCNSFVTurbulenceBaseTasks("NavierStokesApp", WCNSLinearFVTurbulencePhysics);
      20             : registerMooseAction("NavierStokesApp",
      21             :                     WCNSLinearFVTurbulencePhysics,
      22             :                     "add_interpolation_method_physics");
      23             : registerMooseAction("NavierStokesApp", WCNSLinearFVTurbulencePhysics, "add_functor_material");
      24             : 
      25             : InputParameters
      26          30 : WCNSLinearFVTurbulencePhysics::validParams()
      27             : {
      28          30 :   InputParameters params = WCNSFVTurbulencePhysicsBase::validParams();
      29          30 :   params.addClassDescription(
      30             :       "Define a turbulence model for an incompressible or weakly-compressible Navier Stokes "
      31             :       "flow with a linear finite volume discretization");
      32             : 
      33         150 :   params.addParam<std::vector<SolverSystemName>>(
      34             :       "system_names",
      35             :       {"TKE_system", "TKED_system"},
      36             :       "Names of the linear solver systems for each equation. Default is set for K-Epsilon and "
      37             :       "should be adapted for other models");
      38             : 
      39             :   // Not an option
      40          60 :   params.addParam<bool>("mu_t_as_aux_variable",
      41          60 :                         true,
      42             :                         "Whether to use an auxiliary variable instead of a functor material "
      43             :                         "property for the turbulent viscosity");
      44          30 :   params.suppressParameter<bool>("mu_t_as_aux_variable");
      45          30 :   params.suppressParameter<bool>("turbulent_viscosity_two_term_bc_expansion");
      46             : 
      47             :   // Could be implemented when boundary conditions are implemented in turbulence physics
      48          30 :   params.suppressParameter<bool>("tke_two_term_bc_expansion");
      49          30 :   params.suppressParameter<bool>("tked_two_term_bc_expansion");
      50             : 
      51             :   // Not implemented
      52          30 :   params.suppressParameter<MooseEnum>("wall_treatment_T");
      53          30 :   params.suppressParameter<MooseEnum>("tke_face_interpolation");
      54          30 :   params.suppressParameter<MooseEnum>("tked_face_interpolation");
      55             : 
      56             :   // LinearFV-specific parameters
      57          60 :   params.addParam<bool>(
      58             :       "use_nonorthogonal_correction",
      59          60 :       true,
      60             :       "Whether to use a non-orthogonal correction. This can potentially slow down convergence "
      61             :       ", but reduces numerical dispersion on non-orthogonal meshes. Can be safely turned off on "
      62             :       "orthogonal meshes.");
      63          60 :   params.addParamNamesToGroup("use_nonorthogonal_correction", "Numerical scheme");
      64          60 :   params.addParam<InterpolationMethodName>(
      65             :       "tke_advection_interpolation_method_name",
      66             :       "Name of an externally defined FVInterpolationMethod to use for turbulent kinetic energy "
      67             :       "advection. When provided, this overrides 'tke_advection_interpolation'.");
      68          60 :   params.addParam<InterpolationMethodName>(
      69             :       "tked_advection_interpolation_method_name",
      70             :       "Name of an externally defined FVInterpolationMethod to use for turbulent kinetic energy "
      71             :       "dissipation advection. When provided, this overrides 'tked_advection_interpolation'.");
      72          60 :   params.addParamNamesToGroup(
      73             :       "tke_advection_interpolation_method_name tked_advection_interpolation_method_name",
      74             :       "K-Epsilon model numerical");
      75          30 :   return params;
      76           0 : }
      77             : 
      78          30 : WCNSLinearFVTurbulencePhysics::WCNSLinearFVTurbulencePhysics(const InputParameters & parameters)
      79          30 :   : WCNSFVTurbulencePhysicsBase(parameters)
      80             : {
      81          30 :   addRequiredPhysicsTask("add_interpolation_method_physics");
      82             : 
      83          30 :   if (_turbulence_model != "k-epsilon")
      84           0 :     errorDependentParameter("turbulence_handling", "k-epsilon", {"use_nonorthogonal_correction"});
      85          30 :   if (_turbulence_model == "mixing-length")
      86           0 :     paramError("turbulence_handling",
      87             :                "Mixing length is not implemented for the linear finite volume discretization");
      88          30 : }
      89             : 
      90             : void
      91          30 : WCNSLinearFVTurbulencePhysics::addFVInterpolationMethods()
      92             : {
      93          30 :   if (_turbulence_model != "k-epsilon")
      94             :     return;
      95             : 
      96          60 :   if (!isParamValid("tke_advection_interpolation_method_name"))
      97          90 :     addFVAdvectedInterpolationMethod(getParam<MooseEnum>("tke_advection_interpolation"));
      98          60 :   if (!isParamValid("tked_advection_interpolation_method_name"))
      99          90 :     addFVAdvectedInterpolationMethod(getParam<MooseEnum>("tked_advection_interpolation"));
     100             : }
     101             : 
     102             : void
     103          30 : WCNSLinearFVTurbulencePhysics::initializePhysicsAdditional()
     104             : {
     105          30 :   if (_turbulence_model == "k-epsilon")
     106          30 :     getProblem().needSolutionState(1, Moose::SolutionIterationType::Nonlinear);
     107          30 : }
     108             : 
     109             : void
     110           0 : WCNSLinearFVTurbulencePhysics::checkIntegrity() const
     111             : {
     112             :   WCNSFVTurbulencePhysicsBase::checkIntegrity();
     113             : 
     114           0 :   if (_flow_equations_physics &&
     115           0 :       !_flow_equations_physics->getParam<bool>("include_deviatoric_stress"))
     116           0 :     _flow_equations_physics->paramWarning(
     117             :         "include_deviatoric_stress", "This should be set to true when using a turbulence model");
     118           0 : }
     119             : 
     120             : void
     121          30 : WCNSLinearFVTurbulencePhysics::addSolverVariables()
     122             : {
     123          30 :   if (_turbulence_model == "mixing-length" || _turbulence_model == "none")
     124           0 :     return;
     125          30 :   else if (_turbulence_model == "k-epsilon")
     126             :   {
     127             :     // Dont add if the user already defined the variable
     128             :     // Add turbulent kinetic energy variable
     129          30 :     if (!shouldCreateVariable(_tke_name, _blocks, /*error if aux*/ true))
     130           0 :       reportPotentiallyMissedParameters({"system_names"}, "MooseLinearVariableFVReal");
     131          30 :     else if (_define_variables)
     132             :     {
     133          30 :       std::string variable_type = "MooseLinearVariableFVReal";
     134             : 
     135          30 :       auto params = getFactory().getValidParams(variable_type);
     136          30 :       assignBlocks(params, _blocks);
     137          60 :       params.set<SolverSystemName>("solver_sys") = getSolverSystem(_tke_name);
     138             : 
     139          30 :       getProblem().addVariable(variable_type, _tke_name, params);
     140          30 :     }
     141             :     else
     142           0 :       paramError("turbulence_kinetic_energy_variable",
     143           0 :                  "Variable (" + _tke_name +
     144             :                      ") supplied to the WCNSLinearFVTurbulencePhysics does not exist!");
     145             : 
     146             :     // Add turbulent kinetic energy dissipation variable
     147          30 :     if (!shouldCreateVariable(_tked_name, _blocks, /*error if aux*/ true))
     148           0 :       reportPotentiallyMissedParameters({"system_names"}, "MooseLinearVariableFVReal");
     149          30 :     else if (_define_variables)
     150             :     {
     151          30 :       std::string variable_type = "MooseLinearVariableFVReal";
     152             : 
     153          30 :       auto params = getFactory().getValidParams(variable_type);
     154          30 :       assignBlocks(params, _blocks);
     155          60 :       params.set<SolverSystemName>("solver_sys") = getSolverSystem(_tked_name);
     156             : 
     157          30 :       getProblem().addVariable(variable_type, _tked_name, params);
     158          30 :     }
     159             :     else
     160           0 :       paramError("turbulence_kinetic_energy_dissipation_variable",
     161           0 :                  "Variable (" + _tked_name +
     162             :                      ") supplied to the WCNSLinearFVTurbulencePhysics does not exist!");
     163             :   }
     164             : }
     165             : 
     166             : void
     167          30 : WCNSLinearFVTurbulencePhysics::addFVKernels()
     168             : {
     169          30 :   if (_turbulence_model == "none")
     170             :     return;
     171             : 
     172             :   // For linear FV discretization:
     173             :   // We have to add the kernel in the flow/heat/scalar physics with mu_eff instead of two kernels
     174             :   // one with mu, one with mu_turb, and chose one of the two to NOT have the advective term
     175             :   // Also, flux boundary conditions would be executed twice with two kernels
     176             : 
     177             :   // Turbulence models with their own set of equations
     178          30 :   if (_turbulence_model == "k-epsilon")
     179             :   {
     180          30 :     if (isTransient())
     181           0 :       addKEpsilonTimeDerivatives();
     182          30 :     addKEpsilonAdvection();
     183          30 :     addKEpsilonDiffusion();
     184          30 :     addKEpsilonSink();
     185             :   }
     186             : }
     187             : 
     188             : void
     189           0 : WCNSLinearFVTurbulencePhysics::addKEpsilonTimeDerivatives()
     190             : {
     191           0 :   const std::string kernel_type = "LinearFVTimeDerivative";
     192           0 :   InputParameters params = getFactory().getValidParams(kernel_type);
     193           0 :   assignBlocks(params, _blocks);
     194             : 
     195           0 :   params.set<LinearVariableName>("variable") = _tke_name;
     196           0 :   params.set<MooseFunctorName>("factor") = _flow_equations_physics->densityName();
     197           0 :   if (shouldCreateTimeDerivative(_tke_name, _blocks, /*error if already defined*/ false))
     198           0 :     getProblem().addLinearFVKernel(kernel_type, prefix() + "tke_time", params);
     199           0 :   params.set<LinearVariableName>("variable") = _tked_name;
     200           0 :   if (shouldCreateTimeDerivative(_tked_name, _blocks, /*error if already defined*/ false))
     201           0 :     getProblem().addLinearFVKernel(kernel_type, prefix() + "tked_time", params);
     202           0 : }
     203             : 
     204             : void
     205          30 : WCNSLinearFVTurbulencePhysics::addKEpsilonAdvection()
     206             : {
     207             :   const auto tke_method_name =
     208          30 :       isParamValid("tke_advection_interpolation_method_name")
     209          30 :           ? getParam<InterpolationMethodName>("tke_advection_interpolation_method_name")
     210             :           : InterpolationMethodName(
     211         120 :                 std::string(getParam<MooseEnum>("tke_advection_interpolation")));
     212             :   const auto tked_method_name =
     213          30 :       isParamValid("tked_advection_interpolation_method_name")
     214          30 :           ? getParam<InterpolationMethodName>("tked_advection_interpolation_method_name")
     215             :           : InterpolationMethodName(
     216         120 :                 std::string(getParam<MooseEnum>("tked_advection_interpolation")));
     217             : 
     218          30 :   const std::string kernel_type = "LinearFVTurbulentAdvection";
     219          30 :   InputParameters params = getFactory().getValidParams(kernel_type);
     220             : 
     221          30 :   assignBlocks(params, _blocks);
     222             : 
     223          30 :   params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName();
     224          30 :   params.set<InterpolationMethodName>("advected_interp_method_name") = tke_method_name;
     225          60 :   params.set<LinearVariableName>("variable") = _tke_name;
     226          60 :   getProblem().addLinearFVKernel(kernel_type, prefix() + "tke_advection", params);
     227          60 :   params.set<LinearVariableName>("variable") = _tked_name;
     228          30 :   params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     229          60 :   params.set<InterpolationMethodName>("advected_interp_method_name") = tked_method_name;
     230          60 :   getProblem().addLinearFVKernel(kernel_type, prefix() + "tked_advection", params);
     231          60 : }
     232             : 
     233             : void
     234          30 : WCNSLinearFVTurbulencePhysics::addKEpsilonDiffusion()
     235             : {
     236             :   {
     237          30 :     const std::string kernel_type = "LinearFVTurbulentDiffusion";
     238          30 :     InputParameters params = getFactory().getValidParams(kernel_type);
     239          30 :     assignBlocks(params, _blocks);
     240          30 :     params.set<bool>("use_nonorthogonal_correction") =
     241          60 :         getParam<bool>("use_nonorthogonal_correction");
     242             : 
     243             :     // Note: we have to use a single diffusion kernel in case we have a flux BC so it is not applied
     244             :     // twice
     245          60 :     params.set<LinearVariableName>("variable") = _tke_name;
     246          60 :     params.set<MooseFunctorName>("diffusion_coeff") = "mu_eff_tke";
     247          60 :     getProblem().addLinearFVKernel(kernel_type, prefix() + "tke_diffusion_mu", params);
     248             : 
     249          30 :     params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     250          60 :     params.set<LinearVariableName>("variable") = _tked_name;
     251          60 :     params.set<MooseFunctorName>("diffusion_coeff") = "mu_eff_tked";
     252          60 :     getProblem().addLinearFVKernel(kernel_type, prefix() + "tked_diffusion_mu", params);
     253          30 :   }
     254          30 : }
     255             : 
     256             : void
     257          30 : WCNSLinearFVTurbulencePhysics::addKEpsilonSink()
     258             : {
     259         120 :   const std::string u_names[3] = {"u", "v", "w"};
     260             :   {
     261          30 :     const std::string kernel_type = "LinearFVTKESourceSink";
     262          30 :     InputParameters params = getFactory().getValidParams(kernel_type);
     263          30 :     assignBlocks(params, _blocks);
     264          60 :     params.set<LinearVariableName>("variable") = _tke_name;
     265          30 :     params.set<MooseFunctorName>(NS::TKED) = _tked_name;
     266          30 :     params.set<MooseFunctorName>(NS::density) = _flow_equations_physics->densityName();
     267          30 :     params.set<MooseFunctorName>(NS::mu) = _flow_equations_physics->dynamicViscosityName();
     268          30 :     params.set<MooseFunctorName>(NS::mu_t) = _turbulent_viscosity_name;
     269          60 :     params.set<Real>("C_mu") = getParam<Real>("C_mu");
     270          60 :     params.set<Real>("C_pl") = getParam<Real>("C_pl");
     271          30 :     params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     272          30 :     params.set<MooseEnum>("wall_treatment") = _wall_treatment_eps;
     273         120 :     for (const auto d : make_range(dimension()))
     274         120 :       params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
     275          60 :     getProblem().addLinearFVKernel(kernel_type, prefix() + "tke_source_sink", params);
     276          30 :   }
     277             : 
     278             :   {
     279          30 :     const std::string kernel_type = "LinearFVTKEDSourceSink";
     280          30 :     InputParameters params = getFactory().getValidParams(kernel_type);
     281          30 :     assignBlocks(params, _blocks);
     282          60 :     params.set<LinearVariableName>("variable") = _tked_name;
     283          30 :     params.set<MooseFunctorName>(NS::TKE) = _tke_name;
     284          30 :     params.set<MooseFunctorName>(NS::density) = _flow_equations_physics->densityName();
     285          30 :     params.set<MooseFunctorName>(NS::mu) = _flow_equations_physics->dynamicViscosityName();
     286          30 :     params.set<MooseFunctorName>(NS::mu_t) = _turbulent_viscosity_name;
     287          30 :     params.set<std::vector<BoundaryName>>("walls") = _turbulence_walls;
     288          30 :     params.set<MooseEnum>("wall_treatment") = _wall_treatment_eps;
     289          90 :     params.set<MooseFunctorName>("C1_eps") = getParam<MooseFunctorName>("C1_eps");
     290          90 :     params.set<MooseFunctorName>("C2_eps") = getParam<MooseFunctorName>("C2_eps");
     291          60 :     params.set<Real>("C_mu") = getParam<Real>("C_mu");
     292          60 :     params.set<Real>("C_pl") = getParam<Real>("C_pl");
     293         120 :     for (const auto d : make_range(dimension()))
     294         120 :       params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
     295          60 :     getProblem().addLinearFVKernel(kernel_type, prefix() + "tked_source_sink", params);
     296          30 :   }
     297         150 : }
     298             : 
     299             : void
     300          30 : WCNSLinearFVTurbulencePhysics::addFVBCs()
     301             : {
     302         120 :   const std::string u_names[3] = {"u", "v", "w"};
     303             : 
     304          90 :   if (_turbulence_model == "k-epsilon" && getParam<bool>("mu_t_as_aux_variable"))
     305             :   {
     306             :     mooseAssert(_flow_equations_physics, "Should have a flow equation physics");
     307          30 :     const std::string bc_type = "LinearFVTurbulentViscosityWallFunctionBC";
     308          30 :     InputParameters params = getFactory().getValidParams(bc_type);
     309          30 :     params.set<std::vector<BoundaryName>>("boundary") = _turbulence_walls;
     310          60 :     params.set<LinearVariableName>("variable") = _turbulent_viscosity_name;
     311          30 :     params.set<MooseFunctorName>(NS::density) = _flow_equations_physics->densityName();
     312          30 :     params.set<MooseFunctorName>(NS::mu) = _flow_equations_physics->dynamicViscosityName();
     313          30 :     params.set<MooseFunctorName>(NS::TKE) = _tke_name;
     314          60 :     params.set<Real>("C_mu") = getParam<Real>("C_mu");
     315          30 :     params.set<MooseEnum>("wall_treatment") = _wall_treatment_eps;
     316         120 :     for (const auto d : make_range(dimension()))
     317         120 :       params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
     318             : 
     319          60 :     getProblem().addLinearFVBC(bc_type, prefix() + "turbulence_walls", params);
     320             :     // Energy wall function boundary conditions are added in the WCNSFVFluidEnergyPhysics
     321             :     // because it facilitates counting the number of walls, specifying energy wall functors
     322             :     // the same way as for boundary conditions
     323          30 :   }
     324         150 : }
     325             : 
     326             : void
     327          30 : WCNSLinearFVTurbulencePhysics::addFunctorMaterials()
     328             : {
     329             :   // Functor materials for the diffusion coefficients
     330          30 :   if (_turbulence_model == "k-epsilon")
     331             :   {
     332             :     // Since sigma_k = 1 in the standard k-epsilon, this is often unnecessary
     333          30 :     const std::string mat_type = "FunctorEffectiveDynamicViscosity";
     334          30 :     InputParameters params = getFactory().getValidParams(mat_type);
     335          30 :     assignBlocks(params, _blocks);
     336          60 :     params.set<MooseFunctorName>("property_name") = "mu_eff_tke";
     337          30 :     params.set<MooseFunctorName>(NS::mu) = _flow_equations_physics->dynamicViscosityName();
     338          30 :     params.set<MooseFunctorName>(NS::mu_t) = _turbulent_viscosity_name;
     339          60 :     params.set<MooseFunctorName>(NS::mu_t + "_inverse_factor") =
     340          60 :         getParam<MooseFunctorName>("sigma_k");
     341          90 :     getProblem().addMaterial(mat_type, prefix() + "mu_eff_tke", params);
     342             : 
     343          60 :     params.set<MooseFunctorName>("property_name") = "mu_eff_tked";
     344          60 :     params.set<MooseFunctorName>(NS::mu_t + "_inverse_factor") =
     345          60 :         getParam<MooseFunctorName>("sigma_eps");
     346          60 :     getProblem().addMaterial(mat_type, prefix() + "mu_eff_tked", params);
     347          30 :   }
     348          30 : }
     349             : 
     350             : unsigned short
     351          90 : WCNSLinearFVTurbulencePhysics::getNumberAlgebraicGhostingLayersNeeded() const
     352             : {
     353          90 :   return _flow_equations_physics->getNumberAlgebraicGhostingLayersNeeded();
     354             : }

Generated by: LCOV version 1.14