LCOV - code coverage report
Current view: top level - src/physics - WCNSFVFluidHeatTransferPhysicsBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 2bd28b Lines: 152 162 93.8 %
Date: 2025-10-23 22:11:45 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        1371 : WCNSFVFluidHeatTransferPhysicsBase::validParams()
      18             : {
      19        1371 :   InputParameters params = NavierStokesPhysicsBase::validParams();
      20        1371 :   params += WCNSFVCoupledAdvectionPhysicsHelper::validParams();
      21        1371 :   params.addClassDescription("Define the Navier Stokes weakly-compressible energy equation");
      22             : 
      23        1371 :   params += NSFVBase::commonFluidEnergyEquationParams();
      24        1371 :   params.transferParam<bool>(PINSFVEnergyAnisotropicDiffusion::validParams(),
      25             :                              "effective_conductivity");
      26             : 
      27             :   // TODO Remove the parameter once NavierStokesFV syntax has been removed
      28        2742 :   params.addParam<bool>("add_energy_equation",
      29             :                         "Whether to add the energy equation. This parameter is not necessary if "
      30             :                         "using the Physics syntax");
      31        2742 :   params.addParam<bool>("solve_for_enthalpy",
      32        2742 :                         false,
      33             :                         "Whether to solve for the enthalpy or the temperature of the fluid");
      34        2742 :   params.addParam<NonlinearVariableName>(
      35             :       "fluid_temperature_variable", NS::T_fluid, "Name of the fluid temperature variable");
      36             : 
      37        1371 :   params.addParam<UserObjectName>(NS::fluid, "Fluid properties userobject");
      38        1371 :   params.addParamNamesToGroup(NS::fluid, "Material properties");
      39             : 
      40             :   // Initial conditions
      41        2742 :   params.addParam<FunctionName>(
      42             :       "initial_enthalpy",
      43             :       "Initial value of the enthalpy variable, only to be used when solving for enthalpy");
      44             : 
      45             :   // Spatial finite volume discretization scheme
      46        1371 :   params.transferParam<MooseEnum>(NSFVBase::validParams(), "energy_advection_interpolation");
      47        1371 :   params.transferParam<MooseEnum>(NSFVBase::validParams(), "energy_face_interpolation");
      48        1371 :   params.transferParam<bool>(NSFVBase::validParams(), "energy_two_term_bc_expansion");
      49             : 
      50        2742 :   params.addParamNamesToGroup("specific_heat thermal_conductivity thermal_conductivity_blocks "
      51             :                               "use_external_enthalpy_material",
      52             :                               "Material properties");
      53        2742 :   params.addParamNamesToGroup("energy_advection_interpolation energy_face_interpolation "
      54             :                               "energy_two_term_bc_expansion",
      55             :                               "Numerical scheme");
      56        2742 :   params.addParamNamesToGroup("energy_inlet_types energy_inlet_functors",
      57             :                               "Inlet boundary conditions");
      58        2742 :   params.addParamNamesToGroup("energy_wall_types energy_wall_functors", "Wall boundary conditions");
      59             : 
      60        1371 :   return params;
      61           0 : }
      62             : 
      63        1371 : WCNSFVFluidHeatTransferPhysicsBase::WCNSFVFluidHeatTransferPhysicsBase(
      64        1371 :     const InputParameters & parameters)
      65             :   : NavierStokesPhysicsBase(parameters),
      66             :     WCNSFVCoupledAdvectionPhysicsHelper(this),
      67        1371 :     _has_energy_equation(
      68        2742 :         isParamValid("add_energy_equation")
      69        4113 :             ? getParam<bool>("add_energy_equation")
      70        3337 :             : (usingNavierStokesFVSyntax() ? isParamSetByUser("energy_inlet_functors") : true)),
      71        2742 :     _solve_for_enthalpy(getParam<bool>("solve_for_enthalpy")),
      72        1371 :     _fluid_enthalpy_name(getSpecificEnthalpyName()),
      73        2742 :     _fluid_temperature_name(getParam<NonlinearVariableName>("fluid_temperature_variable")),
      74        1371 :     _specific_heat_name(getParam<MooseFunctorName>("specific_heat")),
      75        4113 :     _thermal_conductivity_blocks(
      76        1371 :         parameters.isParamValid("thermal_conductivity_blocks")
      77        1371 :             ? getParam<std::vector<std::vector<SubdomainName>>>("thermal_conductivity_blocks")
      78             :             : std::vector<std::vector<SubdomainName>>()),
      79        2742 :     _thermal_conductivity_name(getParam<std::vector<MooseFunctorName>>("thermal_conductivity")),
      80        2742 :     _ambient_convection_blocks(
      81             :         getParam<std::vector<std::vector<SubdomainName>>>("ambient_convection_blocks")),
      82        2742 :     _ambient_convection_alpha(getParam<std::vector<MooseFunctorName>>("ambient_convection_alpha")),
      83        2742 :     _ambient_temperature(getParam<std::vector<MooseFunctorName>>("ambient_temperature")),
      84        2742 :     _energy_inlet_types(getParam<MultiMooseEnum>("energy_inlet_types")),
      85        2742 :     _energy_inlet_functors(getParam<std::vector<MooseFunctorName>>("energy_inlet_functors")),
      86        2742 :     _energy_wall_types(getParam<MultiMooseEnum>("energy_wall_types")),
      87        4113 :     _energy_wall_functors(getParam<std::vector<MooseFunctorName>>("energy_wall_functors"))
      88             : {
      89             :   // For compatibility with Modules/NavierStokesFV syntax
      90        1371 :   if (!_has_energy_equation)
      91             :     return;
      92             : 
      93         798 :   if (_solve_for_enthalpy)
      94          76 :     saveSolverVariableName(_fluid_enthalpy_name);
      95             :   else
      96         722 :     saveSolverVariableName(_fluid_temperature_name);
      97             : 
      98             :   // set block restrictions if not set by user
      99             :   // This should probably be done for all the coupled physics, tbd
     100        1596 :   if (!isParamSetByUser("block"))
     101         785 :     _blocks = _flow_equations_physics->blocks();
     102             : 
     103             :   // Parameter checks
     104        1596 :   checkSecondParamSetOnlyIfFirstOneTrue("solve_for_enthalpy", "initial_enthalpy");
     105        1596 :   checkVectorParamsSameLengthIfSet<MooseFunctorName, MooseFunctorName>("ambient_convection_alpha",
     106             :                                                                        "ambient_temperature");
     107        1596 :   checkSecondParamSetOnlyIfFirstOneSet("external_heat_source", "external_heat_source_coeff");
     108             : 
     109             :   // Check boundary parameters if provided.
     110             :   // The boundaries are checked again when the boundary conditions are added as we want
     111             :   // to be able to more boundary conditions to a Physics dynamically
     112        1596 :   if (isParamValid("energy_inlet_types"))
     113        1538 :     checkVectorParamAndMultiMooseEnumLength<MooseFunctorName>("energy_inlet_functors",
     114             :                                                               "energy_inlet_types");
     115        1596 :   if (isParamSetByUser("energy_wall_boundaries"))
     116          94 :     checkVectorParamsSameLengthIfSet<BoundaryName, MooseFunctorName>(
     117             :         "energy_wall_boundaries", "energy_wall_functors", false);
     118        1596 :   if (isParamValid("energy_wall_types"))
     119        1552 :     checkVectorParamAndMultiMooseEnumLength<MooseFunctorName>("energy_wall_functors",
     120             :                                                               "energy_wall_types");
     121           0 : }
     122             : 
     123             : void
     124        1329 : WCNSFVFluidHeatTransferPhysicsBase::addFVKernels()
     125             : {
     126             :   // For compatibility with Modules/NavierStokesFV syntax
     127        1329 :   if (!_has_energy_equation)
     128             :     return;
     129             : 
     130         760 :   if (shouldCreateTimeDerivative(_solve_for_enthalpy ? _fluid_enthalpy_name
     131             :                                                      : _fluid_temperature_name,
     132         760 :                                  _blocks,
     133             :                                  /*error if already defined*/ false))
     134         182 :     addEnergyTimeKernels();
     135             : 
     136         760 :   addEnergyAdvectionKernels();
     137         760 :   addEnergyHeatConductionKernels();
     138        1508 :   if (getParam<std::vector<MooseFunctorName>>("ambient_temperature").size())
     139         243 :     addEnergyAmbientConvection();
     140        1508 :   if (isParamValid("external_heat_source"))
     141         161 :     addEnergyExternalHeatSource();
     142             : }
     143             : 
     144             : void
     145        1319 : WCNSFVFluidHeatTransferPhysicsBase::addFVBCs()
     146             : {
     147             :   // For compatibility with Modules/NavierStokesFV syntax
     148        1319 :   if (!_has_energy_equation)
     149             :     return;
     150             : 
     151         750 :   addEnergyInletBC();
     152         748 :   addEnergyWallBC();
     153         746 :   addEnergyOutletBC();
     154         746 :   addEnergySeparatorBC();
     155             : }
     156             : 
     157             : void
     158       13500 : WCNSFVFluidHeatTransferPhysicsBase::actOnAdditionalTasks()
     159             : {
     160             :   // Turbulence physics would not be initialized before this task
     161       13500 :   if (_current_task == "get_turbulence_physics")
     162        1343 :     _turbulence_physics = getCoupledTurbulencePhysics();
     163       13500 : }
     164             : 
     165             : bool
     166         760 : WCNSFVFluidHeatTransferPhysicsBase::processThermalConductivity()
     167             : {
     168        1518 :   checkBlockwiseConsistency<MooseFunctorName>("thermal_conductivity_blocks",
     169             :                                               {"thermal_conductivity"});
     170             :   bool have_scalar = false;
     171             :   bool have_vector = false;
     172             : 
     173        1537 :   for (unsigned int i = 0; i < _thermal_conductivity_name.size(); ++i)
     174             :   {
     175             :     // First, check if the name is just a number (only in case of isotropic conduction)
     176         779 :     if (MooseUtils::parsesToReal(_thermal_conductivity_name[i]))
     177             :       have_scalar = true;
     178             :     // Now we determine what kind of functor we are dealing with
     179             :     else
     180             :     {
     181         420 :       if (getProblem().hasFunctorWithType<ADReal>(_thermal_conductivity_name[i],
     182         462 :                                                   /*thread_id=*/0) ||
     183          42 :           getProblem().hasFunctorWithType<Real>(_thermal_conductivity_name[i],
     184             :                                                 /*thread_id=*/0))
     185             :         have_scalar = true;
     186             :       else
     187             :       {
     188          42 :         if (getProblem().hasFunctorWithType<ADRealVectorValue>(_thermal_conductivity_name[i],
     189             :                                                                /*thread_id=*/0))
     190             :           have_vector = true;
     191             :         else
     192           0 :           paramError("thermal_conductivity",
     193             :                      "We only allow functor of type Real/ADReal or ADRealVectorValue for thermal "
     194           0 :                      "conductivity! Functor '" +
     195             :                          _thermal_conductivity_name[i] + "' is not of the requested type.");
     196             :       }
     197             :     }
     198             :   }
     199             : 
     200         758 :   if (have_vector && !_porous_medium_treatment)
     201           2 :     paramError("thermal_conductivity", "Cannot use anisotropic diffusion with non-porous flows!");
     202             : 
     203         756 :   if (have_vector == have_scalar)
     204           2 :     paramError("thermal_conductivity",
     205             :                "The entries on thermal conductivity shall either be scalars of vectors, mixing "
     206             :                "them is not supported!");
     207         754 :   return have_vector;
     208             : }
     209             : 
     210             : void
     211        1331 : WCNSFVFluidHeatTransferPhysicsBase::addInitialConditions()
     212             : {
     213             :   // For compatibility with Modules/NavierStokesFV syntax
     214        1331 :   if (!_has_energy_equation)
     215         569 :     return;
     216         764 :   if (!_define_variables && parameters().isParamSetByUser("initial_temperature"))
     217           2 :     paramError(
     218             :         "initial_temperature",
     219             :         "T_fluid is defined externally of WCNSFVFluidHeatTransferPhysicsBase, so should the inital "
     220             :         "condition");
     221             :   // do not set initial conditions if we are not defining variables
     222         760 :   if (!_define_variables)
     223             :   {
     224           0 :     reportPotentiallyMissedParameters({"initial_temperature", "initial_enthalpy"}, "FunctionIC");
     225           0 :     return;
     226             :   }
     227             : 
     228         760 :   InputParameters params = getFactory().getValidParams("FVFunctionIC");
     229         760 :   assignBlocks(params, _blocks);
     230             : 
     231             :   // initial_temperature has a default so we should almost always set it (see shouldCreateIC logic)
     232             :   {
     233             :     bool temperature_ic_used = false;
     234         760 :     if (variableExists(_fluid_temperature_name, false) &&
     235        1406 :         shouldCreateIC(_fluid_temperature_name,
     236             :                        _blocks,
     237        1463 :                        /*whether IC is a default*/ !isParamSetByUser("initial_temperature"),
     238        2166 :                        /*error if already an IC*/ isParamSetByUser("initial_temperature")))
     239             :     {
     240         674 :       params.set<VariableName>("variable") = _fluid_temperature_name;
     241        2022 :       params.set<FunctionName>("function") = getParam<FunctionName>("initial_temperature");
     242             : 
     243        1348 :       getProblem().addFVInitialCondition("FVFunctionIC", _fluid_temperature_name + "_ic", params);
     244             :       temperature_ic_used = true;
     245             :     }
     246             :     // Needed to solve for enthalpy: an initial condition on enthalpy based on the initial
     247             :     // temperature
     248        1596 :     if (isParamValid(NS::fluid) && _solve_for_enthalpy && !isParamValid("initial_enthalpy") &&
     249          76 :         shouldCreateIC(_fluid_enthalpy_name,
     250             :                        _blocks,
     251         798 :                        /*whether IC is a default*/ !isParamSetByUser("initial_temperature"),
     252         836 :                        /*error if already an IC*/ isParamSetByUser("initial_temperature")))
     253             :     {
     254             :       // from the FluidProperties module
     255             :       InputParameters params =
     256          38 :           getFactory().getValidParams("SpecificEnthalpyFromPressureTemperatureIC");
     257          38 :       assignBlocks(params, _blocks);
     258          76 :       params.set<VariableName>("variable") = _fluid_enthalpy_name;
     259          38 :       params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
     260         114 :       params.set<std::vector<VariableName>>("p") = {_flow_equations_physics->getPressureName()};
     261             :       Real temp;
     262         114 :       if (MooseUtils::parsesToReal(getParam<FunctionName>("initial_temperature"), &temp))
     263             :       {
     264          38 :         params.defaultCoupledValue("T", temp, 0);
     265          38 :         params.set<std::vector<VariableName>>("T") = {};
     266             :       }
     267             :       else
     268           0 :         paramError("initial_temperature", "Only Real values supported when solving for enthalpy");
     269         114 :       getProblem().addInitialCondition(
     270          38 :           "SpecificEnthalpyFromPressureTemperatureIC", _fluid_enthalpy_name + "_ic", params);
     271             :       temperature_ic_used = true;
     272          38 :     }
     273             : 
     274        1530 :     if (!temperature_ic_used && isParamSetByUser("initial_temperature"))
     275           0 :       reportPotentiallyMissedParameters({"initial_temperature"}, "FunctionIC");
     276             :   }
     277        2318 :   if (isParamValid("initial_enthalpy") && _solve_for_enthalpy &&
     278          38 :       shouldCreateIC(_fluid_enthalpy_name,
     279             :                      _blocks,
     280             :                      /*whether IC is a default*/ false,
     281             :                      /*error if already an IC*/ false))
     282             :   {
     283          38 :     params.set<VariableName>("variable") = _fluid_enthalpy_name;
     284         114 :     params.set<FunctionName>("function") = getParam<FunctionName>("initial_enthalpy");
     285             : 
     286          76 :     getProblem().addFVInitialCondition("FVFunctionIC", _fluid_enthalpy_name + "_ic", params);
     287             :   }
     288        1444 :   else if (isParamValid("initial_enthalpy"))
     289           0 :     reportPotentiallyMissedParameters({"initial_enthalpy"}, "FunctionIC");
     290         798 : }
     291             : 
     292             : void
     293          76 : WCNSFVFluidHeatTransferPhysicsBase::defineKOverCpFunctors(const bool use_ad)
     294             : {
     295             :   // Define alpha, the diffusion coefficient when solving for enthalpy, on each block
     296         152 :   for (unsigned int i = 0; i < _thermal_conductivity_name.size(); ++i)
     297             :   {
     298          76 :     const auto object_type = use_ad ? "ADParsedFunctorMaterial" : "ParsedFunctorMaterial";
     299          76 :     InputParameters params = getFactory().getValidParams(object_type);
     300          76 :     assignBlocks(params, _blocks);
     301             :     std::vector<std::string> f_names;
     302          76 :     if (!MooseUtils::parsesToReal(_thermal_conductivity_name[i]))
     303          76 :       f_names.push_back(_thermal_conductivity_name[i]);
     304          76 :     if (!MooseUtils::parsesToReal(getSpecificHeatName()))
     305          76 :       f_names.push_back(getSpecificHeatName());
     306         152 :     params.set<std::vector<std::string>>("functor_names") = f_names;
     307         152 :     params.set<std::string>("expression") =
     308         228 :         _thermal_conductivity_name[i] + "/" + getSpecificHeatName();
     309         152 :     params.set<std::string>("property_name") = _thermal_conductivity_name[i] + "_by_cp";
     310         228 :     getProblem().addMaterial(
     311         152 :         object_type, prefix() + "rho_alpha_from_" + _thermal_conductivity_name[i], params);
     312          76 :   }
     313          76 : }
     314             : 
     315             : unsigned short
     316        3981 : WCNSFVFluidHeatTransferPhysicsBase::getNumberAlgebraicGhostingLayersNeeded() const
     317             : {
     318        7962 :   unsigned short necessary_layers = getParam<unsigned short>("ghost_layers");
     319        3981 :   necessary_layers =
     320        3981 :       std::max(necessary_layers, _flow_equations_physics->getNumberAlgebraicGhostingLayersNeeded());
     321       11943 :   if (getParam<MooseEnum>("energy_face_interpolation") == "skewness-corrected")
     322           0 :     necessary_layers = std::max(necessary_layers, (unsigned short)3);
     323             : 
     324        3981 :   return necessary_layers;
     325             : }

Generated by: LCOV version 1.14