https://mooseframework.inl.gov
WCNSLinearFVFluidHeatTransferPhysics.C
Go to the documentation of this file.
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 
11 #include "WCNSFVFlowPhysics.h"
13 #include "NSFVBase.h"
14 
18 registerMooseAction("NavierStokesApp", WCNSLinearFVFluidHeatTransferPhysics, "add_aux_variable");
19 registerMooseAction("NavierStokesApp", WCNSLinearFVFluidHeatTransferPhysics, "add_aux_kernel");
20 
23 {
25  params.addParam<bool>(
26  "use_nonorthogonal_correction",
27  true,
28  "Whether to use a non-orthogonal correction. This can potentially slow down convergence "
29  ", but reduces numerical dispersion on non-orthogonal meshes. Can be safely turned off on "
30  "orthogonal meshes.");
31  params.set<std::vector<SolverSystemName>>("system_names") = {"energy_system"};
32 
33  // We could split between discretization and solver here.
34  params.addParamNamesToGroup("use_nonorthogonal_correction system_names", "Numerical scheme");
35 
36  // Not implemented
37  params.suppressParameter<bool>("effective_conductivity");
38  // Not needed
39  params.suppressParameter<bool>("add_energy_equation");
40  params.suppressParameter<MooseEnum>("preconditioning");
41 
42  return params;
43 }
44 
46  const InputParameters & parameters)
48 {
50  paramError("porous_medium_treatment", "Porous media not supported at this time");
51  checkSecondParamSetOnlyIfFirstOneTrue("solve_for_enthalpy", NS::fluid);
52 }
53 
54 void
56 {
57  // For compatibility with Modules/NavierStokesFV syntax
59  return;
60 
62 
63  // Dont add if the user already defined the variable
64  if (!shouldCreateVariable(variable_name, _blocks, /*error if aux*/ true))
65  reportPotentiallyMissedParameters({"system_names"}, "MooseLinearVariableFVReal");
66  else if (_define_variables)
67  {
68  const auto var_type = "MooseLinearVariableFVReal";
69  auto params = getFactory().getValidParams(var_type);
70  assignBlocks(params, _blocks);
71  params.set<SolverSystemName>("solver_sys") = getSolverSystem(variable_name);
72  getProblem().addVariable(var_type, variable_name, params);
73  }
74  else
75  paramError(_solve_for_enthalpy ? "solve_for_enthalpy" : "fluid_temperature_variable",
76  "Variable (" + variable_name +
77  ") supplied to the WCNSLinearFVFluidHeatTransferPhysics does not exist!");
78 }
79 
80 void
82 {
83  std::string kernel_type = "LinearFVTimeDerivative";
84  std::string kernel_name = prefix() + "ins_energy_time";
85 
86  InputParameters params = getFactory().getValidParams(kernel_type);
87  params.set<LinearVariableName>("variable") =
89  assignBlocks(params, _blocks);
91  params.set<MooseFunctorName>("factor") = "rho_cp";
92  else
93  params.set<MooseFunctorName>("factor") = _density_name;
94 
95  getProblem().addLinearFVKernel(kernel_type, kernel_name, params);
96 }
97 
98 void
100 {
101  std::string kernel_type = "LinearFVEnergyAdvection";
102  std::string kernel_name = prefix() + "ins_energy_advection";
103 
104  InputParameters params = getFactory().getValidParams(kernel_type);
105  assignBlocks(params, _blocks);
106  if (!getParam<bool>("solve_for_enthalpy"))
107  {
108  params.set<LinearVariableName>("variable") = _fluid_temperature_name;
109  params.set<MooseEnum>("advected_quantity") = "temperature";
110  if (!MooseUtils::isFloat(_specific_heat_name))
111  paramError("specific_heat", "Must be a Real number. Functors not supported at this time");
112  params.set<Real>("cp") = std::atof(_specific_heat_name.c_str());
113  }
114  else
115  params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
116  params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName();
117  params.set<MooseEnum>("advected_interp_method") =
118  getParam<MooseEnum>("energy_advection_interpolation");
119 
120  getProblem().addLinearFVKernel(kernel_type, kernel_name, params);
121 }
122 
123 void
125 {
126  const auto num_blocks = _thermal_conductivity_blocks.size();
127  const auto num_used_blocks = num_blocks ? num_blocks : 1;
128 
129  for (const auto block_i : make_range(num_used_blocks))
130  {
131  std::string block_name = "";
132  if (num_blocks)
133  block_name = Moose::stringify(_thermal_conductivity_blocks[block_i]);
134  else
135  block_name = "all";
136 
137  const std::string kernel_type = "LinearFVDiffusion";
138  InputParameters params = getFactory().getValidParams(kernel_type);
139  if (!_solve_for_enthalpy)
140  {
141  params.set<LinearVariableName>("variable") = _fluid_temperature_name;
142  params.set<MooseFunctorName>("diffusion_coeff") =
143  _thermal_conductivity_name[block_i] + (_has_turbulence_model ? "_plus_kt" : "");
144  }
145  else
146  {
147  params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
148  const auto th_cond_name =
149  _thermal_conductivity_name[block_i] + (_has_turbulence_model ? "_plus_kt" : "");
150  params.set<MooseFunctorName>("diffusion_coeff") = th_cond_name + "_by_cp";
151  }
152  std::vector<SubdomainName> block_names =
153  num_blocks ? _thermal_conductivity_blocks[block_i] : _blocks;
154  assignBlocks(params, block_names);
155  // NOTE: vector conductivities not supported at this time
156  bool has_vector = processThermalConductivity();
157  if (has_vector)
158  paramError("thermal_conductivity",
159  "Vector thermal conductivities not currently supported with the linear finite "
160  "volume discretization");
161 
162  params.set<bool>("use_nonorthogonal_correction") =
163  getParam<bool>("use_nonorthogonal_correction");
164 
166  kernel_type, prefix() + "ins_energy_diffusion_" + block_name, params);
167  }
168 }
169 
170 void
172 {
173  unsigned int num_convection_blocks = _ambient_convection_blocks.size();
174  unsigned int num_used_blocks = num_convection_blocks ? num_convection_blocks : 1;
175 
176  const std::string kernel_type = "LinearFVVolumetricHeatTransfer";
177  InputParameters params = getFactory().getValidParams(kernel_type);
178  params.set<LinearVariableName>("variable") =
180  params.set<VariableName>(NS::T_fluid) = _fluid_temperature_name;
181  params.set<bool>("is_solid") = false;
182 
183  for (unsigned int block_i = 0; block_i < num_used_blocks; ++block_i)
184  {
185  std::string block_name = "";
186  if (num_convection_blocks)
187  {
188  params.set<std::vector<SubdomainName>>("block") = _ambient_convection_blocks[block_i];
189  block_name = Moose::stringify(_ambient_convection_blocks[block_i]);
190  }
191  else
192  {
193  assignBlocks(params, _blocks);
194  block_name = std::to_string(block_i);
195  }
196 
197  params.set<MooseFunctorName>("h_solid_fluid") = _ambient_convection_alpha[block_i];
198  params.set<VariableName>(NS::T_solid) = _ambient_temperature[block_i];
199 
201  kernel_type, prefix() + "ambient_convection_" + block_name, params);
202  }
203 }
204 
205 void
207 {
208  const std::string kernel_type = "LinearFVSource";
209  InputParameters params = getFactory().getValidParams(kernel_type);
210  params.set<LinearVariableName>("variable") =
212  assignBlocks(params, _blocks);
213  params.set<MooseFunctorName>("source_density") =
214  getParam<MooseFunctorName>("external_heat_source");
215  params.set<MooseFunctorName>("scaling_factor") =
216  std::to_string(getParam<Real>("external_heat_source_coeff"));
217 
218  getProblem().addLinearFVKernel(kernel_type, prefix() + "external_heat_source", params);
219 }
220 
221 void
223 {
225  {
226  // Dont add if the user already defined the variable
228  /*error_if_aux=*/false))
230  getProblem().getVariable(0, _fluid_temperature_name).blocks());
231  else if (_define_variables)
232  {
233  const auto var_type = "MooseLinearVariableFVReal";
234  auto params = getFactory().getValidParams(var_type);
235  assignBlocks(params, _blocks);
237  }
238  else
239  paramError("fluid_temperature_variable",
240  "Variable (" + _fluid_temperature_name +
241  ") supplied to the WCNSLinearFVFluidHeatTransferPhysics does not exist!");
242  }
243 }
244 
245 void
247 {
249  {
250  // Keep temperature updated
251  const std::string kernel_type = "FunctorAux";
252  InputParameters params = getFactory().getValidParams(kernel_type);
253  params.set<AuxVariableName>("variable") = _fluid_temperature_name;
254  assignBlocks(params, _blocks);
255  params.set<MooseFunctorName>("functor") = "T_from_p_h";
256  params.set<ExecFlagEnum>("execute_on") = {EXEC_NONLINEAR};
257  getProblem().addAuxKernel(kernel_type, prefix() + "update_temperature", params);
258  }
259 }
260 
261 void
263 {
264  const auto & inlet_boundaries = _flow_equations_physics->getInletBoundaries();
265  // These are parameter errors for now. If Components add boundaries to Physics, the error
266  // may not be due to parameters anymore.
267  if (inlet_boundaries.size() != _energy_inlet_types.size())
268  paramError("energy_inlet_types",
269  "Energy inlet types (size " + std::to_string(_energy_inlet_types.size()) +
270  ") should be the same size as inlet_boundaries (size " +
271  std::to_string(inlet_boundaries.size()) + ")");
272  if (inlet_boundaries.size() != _energy_inlet_functors.size())
273  paramError("energy_inlet_functors",
274  "Energy inlet functors (size " + std::to_string(_energy_inlet_functors.size()) +
275  ") should be the same size as inlet_boundaries (size " +
276  std::to_string(inlet_boundaries.size()) + ")");
277 
278  for (const auto bc_ind : index_range(_energy_inlet_types))
279  {
280  if (_energy_inlet_types[bc_ind] == "fixed-temperature")
281  {
282  const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
283  InputParameters params = getFactory().getValidParams(bc_type);
284  params.set<LinearVariableName>("variable") = _fluid_temperature_name;
285  params.set<MooseFunctorName>("functor") = _energy_inlet_functors[bc_ind];
286  params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]};
287 
289  bc_type, _fluid_temperature_name + "_" + inlet_boundaries[bc_ind], params);
290 
291  // Boundary condition on temperature must be forwarded to enthalpy
293  {
294  params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
295  params.set<MooseFunctorName>("functor") = "h_from_p_T";
297  bc_type, _fluid_enthalpy_name + "_" + inlet_boundaries[bc_ind], params);
298  }
299  }
300  else if (_energy_inlet_types[bc_ind] == "heatflux")
301  paramError("energy_inlet_types", "Heat flux inlet boundary conditions not yet supported");
302  else if (_energy_inlet_types[bc_ind] == "flux-mass" ||
303  _energy_inlet_types[bc_ind] == "flux-velocity")
304  paramError("energy_inlet_types", "Flux inlet boundary conditions not yet supported");
305  }
306 }
307 
308 void
310 {
311  const auto & wall_boundaries = isParamSetByUser("energy_wall_boundaries")
312  ? getParam<std::vector<BoundaryName>>("energy_wall_boundaries")
314  if (wall_boundaries.size() != _energy_wall_types.size())
315  paramError("energy_wall_types",
316  "Energy wall types (size " + std::to_string(_energy_wall_types.size()) +
317  ") should be the same size as wall_boundaries (size " +
318  std::to_string(wall_boundaries.size()) + ")");
319  if (wall_boundaries.size() != _energy_wall_functors.size())
320  paramError("energy_wall_functors",
321  "Energy wall functors (size " + std::to_string(_energy_wall_functors.size()) +
322  ") should be the same size as wall_boundaries (size " +
323  std::to_string(wall_boundaries.size()) + ")");
324 
325  for (unsigned int bc_ind = 0; bc_ind < _energy_wall_types.size(); ++bc_ind)
326  {
327  if (_energy_wall_types[bc_ind] == "fixed-temperature")
328  {
329  const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
330  InputParameters params = getFactory().getValidParams(bc_type);
331  params.set<LinearVariableName>("variable") = _fluid_temperature_name;
332  params.set<MooseFunctorName>("functor") = _energy_wall_functors[bc_ind];
333  params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
334 
336  bc_type, _fluid_temperature_name + "_" + wall_boundaries[bc_ind], params);
337 
338  // Boundary condition on temperature must be forwarded to enthalpy
340  {
341  params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
342  params.set<MooseFunctorName>("functor") = "h_from_p_T";
344  bc_type, _fluid_enthalpy_name + "_" + wall_boundaries[bc_ind], params);
345  }
346  }
347  else if (_energy_wall_types[bc_ind] == "heatflux")
348  {
349  const std::string bc_type = "LinearFVAdvectionDiffusionFunctorNeumannBC";
350  InputParameters params = getFactory().getValidParams(bc_type);
352  params.set<LinearVariableName>("variable") = var_name;
353  params.set<MooseFunctorName>("functor") = _energy_wall_functors[bc_ind];
354  params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
355 
357  bc_type, var_name + "_heatflux_" + wall_boundaries[bc_ind], params);
358  }
359  else if (_energy_wall_types[bc_ind] == "convection")
360  {
361  const std::string bc_type = "LinearFVConvectiveHeatTransferBC";
362  InputParameters params = getFactory().getValidParams(bc_type);
363  params.set<LinearVariableName>("variable") =
365  params.set<MooseFunctorName>(NS::T_fluid) = _fluid_temperature_name;
366  const auto Tinf_htc_functors =
367  MooseUtils::split(_energy_wall_functors[bc_ind], /*delimiter=*/":", /*max_count=*/1);
368  if (Tinf_htc_functors.size() != 2)
369  paramError("energy_wall_functors",
370  "'convection' wall types require two functors specified as "
371  "<Tinf_functor>:<htc_functor>.");
372  params.set<MooseFunctorName>(NS::T_solid) = Tinf_htc_functors[0];
373  params.set<MooseFunctorName>("h") = Tinf_htc_functors[1];
374  params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
375 
377  bc_type,
379  wall_boundaries[bc_ind],
380  params);
381  }
382  else
383  paramError(
384  "energy_wall_types", _energy_wall_types[bc_ind], " wall type is currently unsupported.");
385  }
386 }
387 
388 void
390 {
391  const auto & outlet_boundaries = _flow_equations_physics->getOutletBoundaries();
392  if (outlet_boundaries.empty())
393  return;
394 
395  for (const auto & outlet_bdy : outlet_boundaries)
396  {
397  const std::string bc_type = "LinearFVAdvectionDiffusionOutflowBC";
399  InputParameters params = getFactory().getValidParams(bc_type);
400  params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
401  params.set<bool>("use_two_term_expansion") = getParam<bool>("energy_two_term_bc_expansion");
402 
403  params.set<LinearVariableName>("variable") = variable_name;
404  getProblem().addLinearFVBC(bc_type, variable_name + "_" + outlet_bdy, params);
405  }
406 }
407 
408 void
410 {
411  // For compatibility with Modules/NavierStokesFV syntax
413  return;
414 
415  // Note that this material choice would not work for Newton-INSFV + solve_for_enthalpy
416  const auto object_type = "LinearFVEnthalpyFunctorMaterial";
417 
418  InputParameters params = getFactory().getValidParams(object_type);
419  assignBlocks(params, _blocks);
420  params.set<MooseFunctorName>(NS::pressure) = _flow_equations_physics->getPressureName();
421  params.set<MooseFunctorName>(NS::T_fluid) = _fluid_temperature_name;
422  params.set<MooseFunctorName>(NS::specific_enthalpy) = _fluid_enthalpy_name;
423  if (isParamValid(NS::fluid))
424  params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
425 
427  {
428  if (!isParamValid(NS::fluid))
429  {
430  if (!getProblem().hasFunctor("h_from_p_T_functor", 0) ||
431  !getProblem().hasFunctor("T_from_p_h_functor", 0))
433  "Either 'fp' must be specified or the 'h_from_p_T_functor' and "
434  "'T_from_p_h_functor' must be defined outside the Physics");
435  // Note: we could define those in the Physics if cp is constant
436  params.set<MooseFunctorName>("h_from_p_T_functor") = "h_from_p_T_functor";
437  params.set<MooseFunctorName>("T_from_p_h_functor") = "T_from_p_h_functor";
438  }
439  }
440  // If we are solving for enthalpy, we need this to compute temperature from p & h
441  // Else we don't really need it
443  getProblem().addMaterial(object_type, prefix() + "enthalpy_material", params);
444 
447  /*use ad*/ false);
448 }
std::string prefix() const
WCNSLinearFVFluidHeatTransferPhysics(const InputParameters &parameters)
MooseFunctorName _specific_heat_name
Name of the specific heat material property.
void assignBlocks(InputParameters &params, const std::vector< SubdomainName > &blocks) const
bool shouldCreateVariable(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool error_if_aux)
const MooseFunctorName _density_name
Name of the density material property.
Factory & getFactory()
void paramError(const std::string &param, Args... args) const
const std::vector< BoundaryName > & getOutletBoundaries() const
Get the outlet boundaries.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
registerNavierStokesPhysicsBaseTasks("NavierStokesApp", WCNSLinearFVFluidHeatTransferPhysics)
const std::vector< BoundaryName > & getInletBoundaries() const
Get the inlet boundaries.
std::vector< MooseFunctorName > _ambient_temperature
Name of the solid domain temperature for each block-group.
virtual void addMaterial(const std::string &material_name, const std::string &name, InputParameters &parameters)
static const std::string T_solid
Definition: NS.h:111
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
const std::vector< SubdomainName > & blocks() const
void reportPotentiallyMissedParameters(const std::vector< std::string > &param_names, const std::string &object_type, const std::string &object_name="") const
unsigned int size() const
static const std::string fluid
Definition: NS.h:88
bool _has_turbulence_model
Because of the Modules/navierStokesFV syntax, a turbulence physics often exists without a model we sa...
virtual void addAuxKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
VariableName _fluid_temperature_name
Fluid temperature name.
virtual void addAuxVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
std::vector< std::vector< SubdomainName > > _ambient_convection_blocks
Vector of subdomain groups where we want to have different ambient convection.
MultiMooseEnum _energy_wall_types
Energy wall boundary types.
std::vector< SubdomainName > _blocks
std::vector< MooseFunctorName > _energy_wall_functors
Functors describing the wall boundary values. See energy_wall_types for what the functors actually re...
void suppressParameter(const std::string &name)
MultiMooseEnum _energy_inlet_types
Energy inlet boundary types.
virtual FEProblemBase & getProblem()
registerMooseAction("NavierStokesApp", WCNSLinearFVFluidHeatTransferPhysics, "add_aux_variable")
const SolverSystemName & getSolverSystem(unsigned int variable_index) const
static const std::string T_fluid
Definition: NS.h:110
void addEnergyTimeKernels() override
Functions adding kernels for the incompressible / weakly compressible energy equation.
Creates all the objects needed to solve the Navier Stokes energy equation.
const bool _porous_medium_treatment
Switch to show if porous medium treatment is requested or not.
std::string stringify(const T &t)
const VariableName _fluid_enthalpy_name
Name of the fluid specific enthalpy.
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
const bool _has_energy_equation
A boolean to help compatibility with the old Modules/NavierStokesFV syntax.
Creates all the objects needed to solve the Navier Stokes energy equation using a linear finite volum...
bool variableExists(const VariableName &var_name, bool error_if_aux) const
bool checkBlockRestrictionIdentical(const std::string &object_name, const std::vector< SubdomainName > &blocks, const bool error_if_not_identical=true) const
bool _define_variables
Whether to define variables if they do not exist.
virtual void addLinearFVKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
std::vector< std::vector< SubdomainName > > _thermal_conductivity_blocks
Vector of subdomain groups where we want to have different thermal conduction.
const ExecFlagType EXEC_NONLINEAR
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool processThermalConductivity()
Process thermal conductivity (multiple functor input options are available).
std::vector< MooseFunctorName > _energy_inlet_functors
Functors describing the inlet boundary values. See energy_inlet_types for what the functors actually ...
virtual void addLinearFVBC(const std::string &fv_bc_name, const std::string &name, InputParameters &parameters)
static const std::string pressure
Definition: NS.h:57
const UserObjectName & rhieChowUOName() const
Return the name of the Rhie Chow user object.
std::vector< MooseFunctorName > _thermal_conductivity_name
Name of the thermal conductivity functor for each block-group.
IntRange< T > make_range(T beg, T end)
const bool _solve_for_enthalpy
User-selected option to solve for enthalpy.
void addEnergyInletBC() override
Functions adding boundary conditions for the incompressible / weakly compressible energy equation...
registerWCNSFVFluidHeatTransferPhysicsBaseTasks("NavierStokesApp", WCNSLinearFVFluidHeatTransferPhysics)
std::vector< MooseFunctorName > _ambient_convection_alpha
Name of the ambient convection heat transfer coefficients for each block-group.
bool isParamValid(const std::string &name) const
void defineEffectiveThermalDiffusionCoeffFunctors(const bool use_ad)
Define the effective diffusion coefficient when:
bool hasFunctor(const std::string &name, const THREAD_ID tid) const
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count)
void checkSecondParamSetOnlyIfFirstOneTrue(const std::string &param1, const std::string &param2) const
bool isParamSetByUser(const std::string &name) const
const WCNSFVFlowPhysicsBase * _flow_equations_physics
Flow physics.
auto index_range(const T &sizable)
const std::vector< BoundaryName > & getWallBoundaries() const
Get the wall boundaries.
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
static const std::string specific_enthalpy
Definition: NS.h:69
const NonlinearVariableName & getPressureName() const