LCOV - code coverage report
Current view: top level - src/physics - WCNSFVFluidHeatTransferPhysicsBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: #32971 (54bef8) with base c6cf66 Lines: 167 180 92.8 %
Date: 2026-05-29 20:37:52 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "WCNSFVFluidHeatTransferPhysicsBase.h"
      11             : #include "WCNSFVCoupledAdvectionPhysicsHelper.h"
      12             : #include "WCNSFVFlowPhysics.h"
      13             : #include "PINSFVEnergyAnisotropicDiffusion.h"
      14             : #include "NSFVBase.h"
      15             : 
      16             : InputParameters
      17         773 : WCNSFVFluidHeatTransferPhysicsBase::validParams()
      18             : {
      19         773 :   InputParameters params = NavierStokesPhysicsBase::validParams();
      20         773 :   params += WCNSFVCoupledAdvectionPhysicsHelper::validParams();
      21         773 :   params.addClassDescription("Define the Navier Stokes weakly-compressible energy equation");
      22             : 
      23         773 :   params += NSFVBase::commonFluidEnergyEquationParams();
      24         773 :   params.transferParam<bool>(PINSFVEnergyAnisotropicDiffusion::validParams(),
      25             :                              "effective_conductivity");
      26        1546 :   params.addParamNamesToGroup("effective_conductivity", "Material properties");
      27             : 
      28             :   // TODO Remove the parameter once NavierStokesFV syntax has been removed
      29        1546 :   params.addParam<bool>("add_energy_equation",
      30             :                         "Whether to add the energy equation. This parameter is not necessary if "
      31             :                         "using the Physics syntax");
      32        1546 :   params.addParam<bool>("solve_for_enthalpy",
      33        1546 :                         false,
      34             :                         "Whether to solve for the enthalpy or the temperature of the fluid");
      35        1546 :   params.addParam<NonlinearVariableName>(
      36             :       "fluid_temperature_variable", NS::T_fluid, "Name of the fluid temperature variable");
      37             : 
      38         773 :   params.addParam<UserObjectName>(NS::fluid, "Fluid properties userobject");
      39         773 :   params.addParamNamesToGroup(NS::fluid, "Material properties");
      40             : 
      41             :   // Initial conditions
      42        1546 :   params.addParam<FunctionName>(
      43             :       "initial_enthalpy",
      44             :       "Initial value of the enthalpy variable, only to be used when solving for enthalpy");
      45             : 
      46             :   // Spatial finite volume discretization scheme
      47         773 :   params.transferParam<MooseEnum>(NSFVBase::validParams(), "energy_advection_interpolation");
      48         773 :   params.transferParam<MooseEnum>(NSFVBase::validParams(), "energy_face_interpolation");
      49         773 :   params.transferParam<bool>(NSFVBase::validParams(), "energy_two_term_bc_expansion");
      50             : 
      51        1546 :   params.addParamNamesToGroup("specific_heat thermal_conductivity thermal_conductivity_blocks "
      52             :                               "use_external_enthalpy_material",
      53             :                               "Material properties");
      54        1546 :   params.addParamNamesToGroup("energy_advection_interpolation energy_face_interpolation "
      55             :                               "energy_two_term_bc_expansion",
      56             :                               "Numerical scheme");
      57        1546 :   params.addParamNamesToGroup("energy_inlet_types energy_inlet_functors",
      58             :                               "Inlet boundary conditions");
      59        1546 :   params.addParamNamesToGroup("energy_wall_boundaries energy_wall_types energy_wall_functors",
      60             :                               "Wall boundary conditions");
      61             : 
      62         773 :   return params;
      63           0 : }
      64             : 
      65         773 : WCNSFVFluidHeatTransferPhysicsBase::WCNSFVFluidHeatTransferPhysicsBase(
      66         773 :     const InputParameters & parameters)
      67             :   : NavierStokesPhysicsBase(parameters),
      68             :     WCNSFVCoupledAdvectionPhysicsHelper(this),
      69         773 :     _has_energy_equation(
      70        1546 :         isParamValid("add_energy_equation")
      71        2319 :             ? getParam<bool>("add_energy_equation")
      72        1791 :             : (usingNavierStokesFVSyntax() ? isParamSetByUser("energy_inlet_functors") : true)),
      73        1546 :     _solve_for_enthalpy(getParam<bool>("solve_for_enthalpy")),
      74         773 :     _fluid_enthalpy_name(getSpecificEnthalpyName()),
      75        1546 :     _fluid_temperature_name(getParam<NonlinearVariableName>("fluid_temperature_variable")),
      76         773 :     _specific_heat_name(getParam<MooseFunctorName>("specific_heat")),
      77        2319 :     _thermal_conductivity_blocks(
      78         773 :         parameters.isParamValid("thermal_conductivity_blocks")
      79         773 :             ? getParam<std::vector<std::vector<SubdomainName>>>("thermal_conductivity_blocks")
      80             :             : std::vector<std::vector<SubdomainName>>()),
      81        1546 :     _thermal_conductivity_name(getParam<std::vector<MooseFunctorName>>("thermal_conductivity")),
      82        1546 :     _ambient_convection_blocks(
      83             :         getParam<std::vector<std::vector<SubdomainName>>>("ambient_convection_blocks")),
      84        1546 :     _ambient_convection_alpha(getParam<std::vector<MooseFunctorName>>("ambient_convection_alpha")),
      85        1546 :     _ambient_temperature(getParam<std::vector<MooseFunctorName>>("ambient_temperature")),
      86        1546 :     _energy_inlet_types(getParam<MultiMooseEnum>("energy_inlet_types")),
      87        1546 :     _energy_inlet_functors(getParam<std::vector<MooseFunctorName>>("energy_inlet_functors")),
      88        1546 :     _energy_wall_types(getParam<MultiMooseEnum>("energy_wall_types")),
      89        2319 :     _energy_wall_functors(getParam<std::vector<MooseFunctorName>>("energy_wall_functors"))
      90             : {
      91             :   // For compatibility with Modules/NavierStokesFV syntax
      92         773 :   if (!_has_energy_equation)
      93             :     return;
      94             : 
      95         488 :   if (_solve_for_enthalpy)
      96          41 :     saveSolverVariableName(_fluid_enthalpy_name);
      97             :   else
      98         447 :     saveSolverVariableName(_fluid_temperature_name);
      99             : 
     100             :   // set block restrictions if not set by user
     101             :   // This should probably be done for all the coupled physics, tbd
     102         976 :   if (!isParamSetByUser("block"))
     103         478 :     _blocks = _flow_equations_physics->blocks();
     104             : 
     105             :   // Parameter checks
     106         976 :   checkSecondParamSetOnlyIfFirstOneTrue("solve_for_enthalpy", "initial_enthalpy");
     107         976 :   checkVectorParamsSameLengthIfSet<MooseFunctorName, MooseFunctorName>("ambient_convection_alpha",
     108             :                                                                        "ambient_temperature");
     109         976 :   checkSecondParamSetOnlyIfFirstOneSet("external_heat_source", "external_heat_source_coeff");
     110             : 
     111             :   // Check boundary parameters if provided.
     112             :   // The boundaries are checked again when the boundary conditions are added as we want
     113             :   // to be able to more boundary conditions to a Physics dynamically
     114         976 :   if (isParamValid("energy_inlet_types"))
     115         942 :     checkVectorParamAndMultiMooseEnumLength<MooseFunctorName>("energy_inlet_functors",
     116             :                                                               "energy_inlet_types");
     117         976 :   if (isParamSetByUser("energy_wall_boundaries"))
     118          48 :     checkVectorParamsSameLengthIfSet<BoundaryName, MooseFunctorName>(
     119             :         "energy_wall_boundaries", "energy_wall_functors", false);
     120         976 :   if (isParamValid("energy_wall_types"))
     121         916 :     checkVectorParamAndMultiMooseEnumLength<MooseFunctorName>("energy_wall_functors",
     122             :                                                               "energy_wall_types");
     123             : 
     124         486 :   addRequiredPhysicsTask("get_turbulence_physics");
     125         486 :   addRequiredPhysicsTask("add_variables_physics");
     126         486 :   addRequiredPhysicsTask("add_ics_physics");
     127         486 :   addRequiredPhysicsTask("add_fv_kernel");
     128         486 :   addRequiredPhysicsTask("add_fv_bc");
     129         972 :   addRequiredPhysicsTask("add_materials_physics");
     130           0 : }
     131             : 
     132             : void
     133         731 : WCNSFVFluidHeatTransferPhysicsBase::addFVKernels()
     134             : {
     135             :   // For compatibility with Modules/NavierStokesFV syntax
     136         731 :   if (!_has_energy_equation)
     137             :     return;
     138             : 
     139         450 :   if (shouldCreateTimeDerivative(_solve_for_enthalpy ? _fluid_enthalpy_name
     140             :                                                      : _fluid_temperature_name,
     141         450 :                                  _blocks,
     142             :                                  /*error if already defined*/ false))
     143         116 :     addEnergyTimeKernels();
     144             : 
     145         450 :   addEnergyAdvectionKernels();
     146         450 :   addEnergyHeatConductionKernels();
     147         888 :   if (getParam<std::vector<MooseFunctorName>>("ambient_temperature").size())
     148         131 :     addEnergyAmbientConvection();
     149         888 :   if (isParamValid("external_heat_source"))
     150         128 :     addEnergyExternalHeatSource();
     151             : }
     152             : 
     153             : void
     154         721 : WCNSFVFluidHeatTransferPhysicsBase::addFVBCs()
     155             : {
     156             :   // For compatibility with Modules/NavierStokesFV syntax
     157         721 :   if (!_has_energy_equation)
     158             :     return;
     159             : 
     160         440 :   addEnergyInletBC();
     161         438 :   addEnergyWallBC();
     162         436 :   addEnergyOutletBC();
     163         436 :   addEnergySeparatorBC();
     164             : }
     165             : 
     166             : void
     167        7518 : WCNSFVFluidHeatTransferPhysicsBase::actOnAdditionalTasks()
     168             : {
     169             :   // Turbulence physics would not be initialized before this task
     170        7518 :   if (_current_task == "get_turbulence_physics")
     171             :   {
     172         745 :     _turbulence_physics = getCoupledTurbulencePhysics();
     173        1983 :     _has_turbulence_model = _turbulence_physics ? _turbulence_physics->hasTurbulenceModel() : false;
     174             :   }
     175        7518 : }
     176             : 
     177             : bool
     178         450 : WCNSFVFluidHeatTransferPhysicsBase::processThermalConductivity()
     179             : {
     180         898 :   checkBlockwiseConsistency<MooseFunctorName>("thermal_conductivity_blocks",
     181             :                                               {"thermal_conductivity"});
     182             :   bool have_scalar = false;
     183             :   bool have_vector = false;
     184             : 
     185         907 :   for (unsigned int i = 0; i < _thermal_conductivity_name.size(); ++i)
     186             :   {
     187             :     // First, check if the name is just a number (only in case of isotropic conduction)
     188         459 :     if (MooseUtils::parsesToReal(_thermal_conductivity_name[i]))
     189             :       have_scalar = true;
     190             :     // Now we determine what kind of functor we are dealing with
     191             :     else
     192             :     {
     193         246 :       if (getProblem().hasFunctorWithType<ADReal>(_thermal_conductivity_name[i],
     194         268 :                                                   /*thread_id=*/0) ||
     195          22 :           getProblem().hasFunctorWithType<Real>(_thermal_conductivity_name[i],
     196             :                                                 /*thread_id=*/0))
     197             :         have_scalar = true;
     198             :       else
     199             :       {
     200          22 :         if (getProblem().hasFunctorWithType<ADRealVectorValue>(_thermal_conductivity_name[i],
     201             :                                                                /*thread_id=*/0))
     202             :           have_vector = true;
     203           0 :         else if (getProblem().hasFunctor(_thermal_conductivity_name[i],
     204             :                                          /*thread_id=*/0))
     205           0 :           paramError("thermal_conductivity",
     206             :                      "We only allow functor of type Real/ADReal or ADRealVectorValue for thermal "
     207           0 :                      "conductivity! Functor '" +
     208             :                          _thermal_conductivity_name[i] + "' is not of the requested type.");
     209             :         else
     210             :           // If another Physics is creating this functor, we could be running into an order of
     211             :           // creation problem
     212           0 :           paramWarning("thermal_conductivity",
     213           0 :                        "Functor '" + _thermal_conductivity_name[i] +
     214             :                            "' was not found in the Problem. Did you mispell it?");
     215             :       }
     216             :     }
     217             :   }
     218             : 
     219         448 :   if (have_vector && !_porous_medium_treatment)
     220           2 :     paramError("thermal_conductivity", "Cannot use anisotropic diffusion with non-porous flows!");
     221             : 
     222         446 :   if (have_vector && (have_vector == have_scalar))
     223           2 :     paramError("thermal_conductivity",
     224             :                "The entries on thermal conductivity shall either be scalars of vectors, mixing "
     225             :                "them is not supported!");
     226         444 :   return have_vector;
     227             : }
     228             : 
     229             : void
     230         733 : WCNSFVFluidHeatTransferPhysicsBase::addInitialConditions()
     231             : {
     232             :   // For compatibility with Modules/NavierStokesFV syntax
     233         733 :   if (!_has_energy_equation)
     234         281 :     return;
     235         456 :   if (!_define_variables && isParamSetByUser("initial_temperature"))
     236           2 :     paramError(
     237             :         "initial_temperature",
     238             :         "T_fluid is defined externally of WCNSFVFluidHeatTransferPhysicsBase, so should the inital "
     239             :         "condition");
     240             :   // do not set initial conditions if we are not defining variables
     241         450 :   if (!_define_variables)
     242             :   {
     243           0 :     reportPotentiallyMissedParameters({"initial_temperature", "initial_enthalpy"}, "FunctionIC");
     244           0 :     return;
     245             :   }
     246             : 
     247         450 :   InputParameters params = getFactory().getValidParams("FVFunctionIC");
     248         450 :   assignBlocks(params, _blocks);
     249             : 
     250             :   // initial_temperature has a default so we should almost always set it (see shouldCreateIC logic)
     251             :   {
     252             :     bool temperature_ic_used = false;
     253         450 :     if (variableExists(_fluid_temperature_name, false) &&
     254         846 :         shouldCreateIC(_fluid_temperature_name,
     255             :                        _blocks,
     256         873 :                        /*whether IC is a default*/ !isParamSetByUser("initial_temperature"),
     257        1296 :                        /*error if already an IC*/ isParamSetByUser("initial_temperature")))
     258             :     {
     259         406 :       params.set<VariableName>("variable") = _fluid_temperature_name;
     260        1218 :       params.set<FunctionName>("function") = getParam<FunctionName>("initial_temperature");
     261             : 
     262         812 :       getProblem().addFVInitialCondition("FVFunctionIC", _fluid_temperature_name + "_ic", params);
     263             :       temperature_ic_used = true;
     264             :     }
     265             :     // Needed to solve for enthalpy: an initial condition on enthalpy based on the initial
     266             :     // temperature
     267         935 :     if (isParamValid(NS::fluid) && _solve_for_enthalpy && !isParamValid("initial_enthalpy") &&
     268          36 :         shouldCreateIC(_fluid_enthalpy_name,
     269             :                        _blocks,
     270         468 :                        /*whether IC is a default*/ !isParamSetByUser("initial_temperature"),
     271         486 :                        /*error if already an IC*/ isParamSetByUser("initial_temperature")))
     272             :     {
     273             :       // from the FluidProperties module
     274             :       InputParameters params =
     275          18 :           getFactory().getValidParams("SpecificEnthalpyFromPressureTemperatureIC");
     276          18 :       assignBlocks(params, _blocks);
     277          36 :       params.set<VariableName>("variable") = _fluid_enthalpy_name;
     278          18 :       params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
     279          54 :       params.set<std::vector<VariableName>>("p") = {_flow_equations_physics->getPressureName()};
     280             :       Real temp;
     281          54 :       if (MooseUtils::parsesToReal(getParam<FunctionName>("initial_temperature"), &temp))
     282             :       {
     283          18 :         params.defaultCoupledValue("T", temp, 0);
     284          18 :         params.set<std::vector<VariableName>>("T") = {};
     285             :       }
     286             :       else
     287           0 :         paramError("initial_temperature", "Only Real values supported when solving for enthalpy");
     288          54 :       getProblem().addInitialCondition(
     289          18 :           "SpecificEnthalpyFromPressureTemperatureIC", _fluid_enthalpy_name + "_ic", params);
     290             :       temperature_ic_used = true;
     291          18 :     }
     292             : 
     293         908 :     if (!temperature_ic_used && isParamSetByUser("initial_temperature"))
     294           0 :       reportPotentiallyMissedParameters({"initial_temperature"}, "FunctionIC");
     295             :   }
     296        1367 :   if (isParamValid("initial_enthalpy") && _solve_for_enthalpy &&
     297          17 :       shouldCreateIC(_fluid_enthalpy_name,
     298             :                      _blocks,
     299             :                      /*whether IC is a default*/ false,
     300             :                      /*error if already an IC*/ false))
     301             :   {
     302          17 :     params.set<VariableName>("variable") = _fluid_enthalpy_name;
     303          51 :     params.set<FunctionName>("function") = getParam<FunctionName>("initial_enthalpy");
     304             : 
     305          34 :     getProblem().addFVInitialCondition("FVFunctionIC", _fluid_enthalpy_name + "_ic", params);
     306             :   }
     307         866 :   else if (isParamValid("initial_enthalpy"))
     308           0 :     reportPotentiallyMissedParameters({"initial_enthalpy"}, "FunctionIC");
     309         468 : }
     310             : 
     311             : void
     312          47 : WCNSFVFluidHeatTransferPhysicsBase::defineEffectiveThermalDiffusionCoeffFunctors(const bool use_ad)
     313             : {
     314             :   // Define alpha, the diffusion coefficient when solving for enthalpy, on each block
     315          94 :   for (unsigned int i = 0; i < _thermal_conductivity_name.size(); ++i)
     316             :   {
     317          47 :     const auto object_type = use_ad ? "ADParsedFunctorMaterial" : "ParsedFunctorMaterial";
     318          47 :     InputParameters params = getFactory().getValidParams(object_type);
     319          47 :     assignBlocks(params, _blocks);
     320             :     std::vector<std::string> f_names;
     321          47 :     if (!MooseUtils::parsesToReal(_thermal_conductivity_name[i]))
     322          35 :       f_names.push_back(_thermal_conductivity_name[i]);
     323          47 :     if (_solve_for_enthalpy && !MooseUtils::parsesToReal(getSpecificHeatName()))
     324          35 :       f_names.push_back(getSpecificHeatName());
     325             :     const auto th_cond_name =
     326          82 :         _thermal_conductivity_name[i] + (_has_turbulence_model ? "_plus_kt" : "");
     327          47 :     if (!_has_turbulence_model)
     328          70 :       params.set<std::string>("expression") =
     329          35 :           _thermal_conductivity_name[i] +
     330         105 :           (_solve_for_enthalpy ? ("/" + getSpecificHeatName()) : "");
     331             :     else
     332             :     {
     333          12 :       f_names.push_back("k_t");
     334          24 :       params.set<std::string>("expression") =
     335          36 :           "(" + _thermal_conductivity_name[i] + " + k_t) " +
     336          36 :           (_solve_for_enthalpy ? ("/" + getSpecificHeatName()) : "");
     337             :     }
     338          47 :     params.set<std::vector<std::string>>("functor_names") = f_names;
     339         100 :     params.set<std::string>("property_name") = th_cond_name + (_solve_for_enthalpy ? "_by_cp" : "");
     340         141 :     getProblem().addMaterial(
     341         141 :         object_type, prefix() + "rho_alpha_from_" + _thermal_conductivity_name[i], params);
     342          47 :   }
     343          47 : }
     344             : 
     345             : unsigned short
     346        2187 : WCNSFVFluidHeatTransferPhysicsBase::getNumberAlgebraicGhostingLayersNeeded() const
     347             : {
     348        4374 :   unsigned short necessary_layers = getParam<unsigned short>("ghost_layers");
     349        2187 :   necessary_layers =
     350        2187 :       std::max(necessary_layers, _flow_equations_physics->getNumberAlgebraicGhostingLayersNeeded());
     351        6561 :   if (getParam<MooseEnum>("energy_face_interpolation") == "skewness-corrected")
     352           0 :     necessary_layers = std::max(necessary_layers, (unsigned short)3);
     353             : 
     354        2187 :   return necessary_layers;
     355             : }

Generated by: LCOV version 1.14