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  params.addParam<UserObjectName>(NS::fluid, "Fluid properties userobject");
34  params.addParamNamesToGroup(NS::fluid, "Material properties");
35 
36  // We could split between discretization and solver here.
37  params.addParamNamesToGroup("use_nonorthogonal_correction system_names", "Numerical scheme");
38 
39  // Not implemented
40  params.suppressParameter<bool>("effective_conductivity");
41  // Not needed
42  params.suppressParameter<bool>("add_energy_equation");
43  params.suppressParameter<MooseEnum>("preconditioning");
44 
45  return params;
46 }
47 
49  const InputParameters & parameters)
51 {
53  paramError("porous_medium_treatment", "Porous media not supported at this time");
54  checkSecondParamSetOnlyIfFirstOneTrue("solve_for_enthalpy", NS::fluid);
55 }
56 
57 void
59 {
60  // For compatibility with Modules/NavierStokesFV syntax
62  return;
63 
65 
66  // Dont add if the user already defined the variable
67  if (!shouldCreateVariable(variable_name, _blocks, /*error if aux*/ true))
68  reportPotentiallyMissedParameters({"system_names"}, "MooseLinearVariableFVReal");
69  else if (_define_variables)
70  {
71  const auto var_type = "MooseLinearVariableFVReal";
72  auto params = getFactory().getValidParams(var_type);
73  assignBlocks(params, _blocks);
74  params.set<SolverSystemName>("solver_sys") = getSolverSystem(variable_name);
75  getProblem().addVariable(var_type, variable_name, params);
76  }
77  else
78  paramError(_solve_for_enthalpy ? "solve_for_enthalpy" : "fluid_temperature_variable",
79  "Variable (" + variable_name +
80  ") supplied to the WCNSLinearFVFluidHeatTransferPhysics does not exist!");
81 }
82 
83 void
85 {
86  std::string kernel_type = "LinearFVTimeDerivative";
87  std::string kernel_name = prefix() + "ins_energy_time";
88 
89  InputParameters params = getFactory().getValidParams(kernel_type);
90  params.set<LinearVariableName>("variable") =
92  assignBlocks(params, _blocks);
94  params.set<MooseFunctorName>("factor") = "rho_cp";
95  else
96  params.set<MooseFunctorName>("factor") = _density_name;
97 
98  getProblem().addLinearFVKernel(kernel_type, kernel_name, params);
99 }
100 
101 void
103 {
104  std::string kernel_type = "LinearFVEnergyAdvection";
105  std::string kernel_name = prefix() + "ins_energy_advection";
106 
107  InputParameters params = getFactory().getValidParams(kernel_type);
108  assignBlocks(params, _blocks);
109  if (!getParam<bool>("solve_for_enthalpy"))
110  {
111  params.set<LinearVariableName>("variable") = _fluid_temperature_name;
112  params.set<MooseEnum>("advected_quantity") = "temperature";
114  paramError("specific_heat", "Must be a Real number. Functors not supported at this time");
115  params.set<Real>("cp") = std::atof(_specific_heat_name.c_str());
116  }
117  else
118  params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
119  params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName();
120  params.set<MooseEnum>("advected_interp_method") =
121  getParam<MooseEnum>("energy_advection_interpolation");
122 
123  getProblem().addLinearFVKernel(kernel_type, kernel_name, params);
124 }
125 
126 void
128 {
129  const auto num_blocks = _thermal_conductivity_blocks.size();
130  const auto num_used_blocks = num_blocks ? num_blocks : 1;
131 
132  for (const auto block_i : make_range(num_used_blocks))
133  {
134  std::string block_name = "";
135  if (num_blocks)
136  block_name = Moose::stringify(_thermal_conductivity_blocks[block_i]);
137  else
138  block_name = "all";
139 
140  const std::string kernel_type = "LinearFVDiffusion";
141  InputParameters params = getFactory().getValidParams(kernel_type);
142  if (!_solve_for_enthalpy)
143  {
144  params.set<LinearVariableName>("variable") = _fluid_temperature_name;
145  params.set<MooseFunctorName>("diffusion_coeff") = _thermal_conductivity_name[block_i];
146  }
147  else
148  {
149  params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
150  params.set<MooseFunctorName>("diffusion_coeff") =
151  _thermal_conductivity_name[block_i] + "_by_cp";
152  }
153  std::vector<SubdomainName> block_names =
154  num_blocks ? _thermal_conductivity_blocks[block_i] : _blocks;
155  assignBlocks(params, block_names);
156  // NOTE: vector conductivities not supported at this time
157  bool has_vector = processThermalConductivity();
158  if (has_vector)
159  paramError("thermal_conductivity",
160  "Vector thermal conductivities not currently supported with the linear finite "
161  "volume discretization");
162 
163  params.set<bool>("use_nonorthogonal_correction") =
164  getParam<bool>("use_nonorthogonal_correction");
165 
167  kernel_type, prefix() + "ins_energy_diffusion_" + block_name, params);
168  }
169 }
170 
171 void
173 {
174  unsigned int num_convection_blocks = _ambient_convection_blocks.size();
175  unsigned int num_used_blocks = num_convection_blocks ? num_convection_blocks : 1;
176 
177  const std::string kernel_type = "LinearFVVolumetricHeatTransfer";
178  InputParameters params = getFactory().getValidParams(kernel_type);
179  params.set<LinearVariableName>("variable") =
181  params.set<VariableName>(NS::T_fluid) = _fluid_temperature_name;
182  params.set<bool>("is_solid") = false;
183 
184  for (unsigned int block_i = 0; block_i < num_used_blocks; ++block_i)
185  {
186  std::string block_name = "";
187  if (num_convection_blocks)
188  {
189  params.set<std::vector<SubdomainName>>("block") = _ambient_convection_blocks[block_i];
190  block_name = Moose::stringify(_ambient_convection_blocks[block_i]);
191  }
192  else
193  {
194  assignBlocks(params, _blocks);
195  block_name = std::to_string(block_i);
196  }
197 
198  params.set<MooseFunctorName>("h_solid_fluid") = _ambient_convection_alpha[block_i];
199  params.set<VariableName>(NS::T_solid) = _ambient_temperature[block_i];
200 
202  kernel_type, prefix() + "ambient_convection_" + block_name, params);
203  }
204 }
205 
206 void
208 {
209  const std::string kernel_type = "LinearFVSource";
210  InputParameters params = getFactory().getValidParams(kernel_type);
211  params.set<LinearVariableName>("variable") =
213  assignBlocks(params, _blocks);
214  params.set<MooseFunctorName>("source_density") =
215  getParam<MooseFunctorName>("external_heat_source");
216  params.set<MooseFunctorName>("scaling_factor") =
217  std::to_string(getParam<Real>("external_heat_source_coeff"));
218 
219  getProblem().addLinearFVKernel(kernel_type, prefix() + "external_heat_source", params);
220 }
221 
222 void
224 {
226  {
227  // Dont add if the user already defined the variable
229  /*error_if_aux=*/false))
231  getProblem().getVariable(0, _fluid_temperature_name).blocks());
232  else if (_define_variables)
233  {
234  const auto var_type = "MooseLinearVariableFVReal";
235  auto params = getFactory().getValidParams(var_type);
236  assignBlocks(params, _blocks);
238  }
239  else
240  paramError("fluid_temperature_variable",
241  "Variable (" + _fluid_temperature_name +
242  ") supplied to the WCNSLinearFVFluidHeatTransferPhysics does not exist!");
243  }
244 }
245 
246 void
248 {
250  {
251  // Keep temperature updated
252  const std::string kernel_type = "FunctorAux";
253  InputParameters params = getFactory().getValidParams(kernel_type);
254  params.set<AuxVariableName>("variable") = _fluid_temperature_name;
255  assignBlocks(params, _blocks);
256  params.set<MooseFunctorName>("functor") = "T_from_p_h";
257  params.set<ExecFlagEnum>("execute_on") = {EXEC_NONLINEAR};
258  getProblem().addAuxKernel(kernel_type, prefix() + "update_temperature", params);
259  }
260 }
261 
262 void
264 {
265  const auto & inlet_boundaries = _flow_equations_physics->getInletBoundaries();
266  // These are parameter errors for now. If Components add boundaries to Physics, the error
267  // may not be due to parameters anymore.
268  if (inlet_boundaries.size() != _energy_inlet_types.size())
269  paramError("energy_inlet_types",
270  "Energy inlet types (size " + std::to_string(_energy_inlet_types.size()) +
271  ") should be the same size as inlet_boundaries (size " +
272  std::to_string(inlet_boundaries.size()) + ")");
273  if (inlet_boundaries.size() != _energy_inlet_functors.size())
274  paramError("energy_inlet_functors",
275  "Energy inlet functors (size " + std::to_string(_energy_inlet_functors.size()) +
276  ") should be the same size as inlet_boundaries (size " +
277  std::to_string(inlet_boundaries.size()) + ")");
278 
279  for (const auto bc_ind : index_range(_energy_inlet_types))
280  {
281  if (_energy_inlet_types[bc_ind] == "fixed-temperature")
282  {
283  const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
284  InputParameters params = getFactory().getValidParams(bc_type);
285  params.set<LinearVariableName>("variable") = _fluid_temperature_name;
286  params.set<MooseFunctorName>("functor") = _energy_inlet_functors[bc_ind];
287  params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]};
288 
290  bc_type, _fluid_temperature_name + "_" + inlet_boundaries[bc_ind], params);
291 
292  // Boundary condition on temperature must be forwarded to enthalpy
294  {
295  params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
296  params.set<MooseFunctorName>("functor") = "h_from_p_T";
298  bc_type, _fluid_enthalpy_name + "_" + inlet_boundaries[bc_ind], params);
299  }
300  }
301  else if (_energy_inlet_types[bc_ind] == "heatflux")
302  paramError("energy_inlet_types", "Heat flux inlet boundary conditions not yet supported");
303  else if (_energy_inlet_types[bc_ind] == "flux-mass" ||
304  _energy_inlet_types[bc_ind] == "flux-velocity")
305  paramError("energy_inlet_types", "Flux inlet boundary conditions not yet supported");
306  }
307 }
308 
309 void
311 {
312  const auto & wall_boundaries = isParamSetByUser("energy_wall_boundaries")
313  ? getParam<std::vector<BoundaryName>>("energy_wall_boundaries")
315  if (wall_boundaries.size() != _energy_wall_types.size())
316  paramError("energy_wall_types",
317  "Energy wall types (size " + std::to_string(_energy_wall_types.size()) +
318  ") should be the same size as wall_boundaries (size " +
319  std::to_string(wall_boundaries.size()) + ")");
320  if (wall_boundaries.size() != _energy_wall_functors.size())
321  paramError("energy_wall_functors",
322  "Energy wall functors (size " + std::to_string(_energy_wall_functors.size()) +
323  ") should be the same size as wall_boundaries (size " +
324  std::to_string(wall_boundaries.size()) + ")");
325 
326  for (unsigned int bc_ind = 0; bc_ind < _energy_wall_types.size(); ++bc_ind)
327  {
328  if (_energy_wall_types[bc_ind] == "fixed-temperature")
329  {
330  const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
331  InputParameters params = getFactory().getValidParams(bc_type);
332  params.set<LinearVariableName>("variable") = _fluid_temperature_name;
333  params.set<MooseFunctorName>("functor") = _energy_wall_functors[bc_ind];
334  params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
335 
337  bc_type, _fluid_temperature_name + "_" + wall_boundaries[bc_ind], params);
338 
339  // Boundary condition on temperature must be forwarded to enthalpy
341  {
342  params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
343  params.set<MooseFunctorName>("functor") = "h_from_p_T";
345  bc_type, _fluid_enthalpy_name + "_" + wall_boundaries[bc_ind], params);
346  }
347  }
348  else if (_energy_wall_types[bc_ind] == "heatflux")
349  {
350  const std::string bc_type = "LinearFVAdvectionDiffusionFunctorNeumannBC";
351  InputParameters params = getFactory().getValidParams(bc_type);
353  params.set<LinearVariableName>("variable") = var_name;
354  params.set<MooseFunctorName>("functor") = _energy_wall_functors[bc_ind];
355  params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
356 
358  bc_type, var_name + "_heatflux_" + wall_boundaries[bc_ind], params);
359  }
360  else if (_energy_wall_types[bc_ind] == "convection")
361  {
362  const std::string bc_type = "LinearFVConvectiveHeatTransferBC";
363  InputParameters params = getFactory().getValidParams(bc_type);
364  params.set<LinearVariableName>("variable") =
366  params.set<MooseFunctorName>(NS::T_fluid) = _fluid_temperature_name;
367  const auto Tinf_htc_functors =
368  MooseUtils::split(_energy_wall_functors[bc_ind], /*delimiter=*/":", /*max_count=*/1);
369  if (Tinf_htc_functors.size() != 2)
370  paramError("energy_wall_functors",
371  "'convection' wall types require two functors specified as "
372  "<Tinf_functor>:<htc_functor>.");
373  params.set<MooseFunctorName>(NS::T_solid) = Tinf_htc_functors[0];
374  params.set<MooseFunctorName>("h") = Tinf_htc_functors[1];
375  params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
376 
378  bc_type,
380  wall_boundaries[bc_ind],
381  params);
382  }
383  else
384  paramError(
385  "energy_wall_types", _energy_wall_types[bc_ind], " wall type is currently unsupported.");
386  }
387 }
388 
389 void
391 {
392  const auto & outlet_boundaries = _flow_equations_physics->getOutletBoundaries();
393  if (outlet_boundaries.empty())
394  return;
395 
396  for (const auto & outlet_bdy : outlet_boundaries)
397  {
398  const std::string bc_type = "LinearFVAdvectionDiffusionOutflowBC";
400  InputParameters params = getFactory().getValidParams(bc_type);
401  params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
402  params.set<bool>("use_two_term_expansion") = getParam<bool>("energy_two_term_bc_expansion");
403 
404  params.set<LinearVariableName>("variable") = variable_name;
405  getProblem().addLinearFVBC(bc_type, variable_name + "_" + outlet_bdy, params);
406  }
407 }
408 
409 void
411 {
413 
415  {
416  // Define alpha, the diffusion coefficient when solving for enthalpy, on each block
417  for (unsigned int i = 0; i < _thermal_conductivity_name.size(); ++i)
418  {
419  const auto object_type = "ADParsedFunctorMaterial";
420  InputParameters params = getFactory().getValidParams(object_type);
421  assignBlocks(params, _blocks);
422  std::vector<std::string> f_names;
424  f_names.push_back(_thermal_conductivity_name[i]);
426  f_names.push_back(getSpecificHeatName());
427  params.set<std::vector<std::string>>("functor_names") = f_names;
428  params.set<std::string>("expression") =
430  params.set<std::string>("property_name") = _thermal_conductivity_name[i] + "_by_cp";
432  object_type, prefix() + "alpha_from_" + _thermal_conductivity_name[i], params);
433  }
434  }
435 }
std::string prefix() const
WCNSLinearFVFluidHeatTransferPhysics(const InputParameters &parameters)
bool parsesToReal(const std::string &input)
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()
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:107
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
const std::vector< SubdomainName > & blocks() const
unsigned int size() const
static const std::string fluid
Definition: NS.h:87
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.
bool isFloat(const std::string &str)
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...
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count=std::numeric_limits< std::size_t >::max())
void suppressParameter(const std::string &name)
MultiMooseEnum _energy_inlet_types
Energy inlet boundary types.
virtual FEProblemBase & getProblem()
registerMooseAction("NavierStokesApp", WCNSLinearFVFluidHeatTransferPhysics, "add_aux_variable")
virtual UserObjectName rhieChowUOName() const =0
Return the name of the Rhie Chow user object.
const SolverSystemName & getSolverSystem(unsigned int variable_index) const
const MooseFunctorName & getSpecificHeatName() const
Get the name of the specific heat material property.
static const std::string T_fluid
Definition: NS.h:106
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.
void paramError(const std::string &param, Args... args) const
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
bool isParamSetByUser(const std::string &nm) const
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)
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.
void reportPotentiallyMissedParameters(const std::vector< std::string > &param_names, const std::string &object_type) const
void checkSecondParamSetOnlyIfFirstOneTrue(const std::string &param1, const std::string &param2) 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)