https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
18registerMooseAction("NavierStokesApp", WCNSLinearFVFluidHeatTransferPhysics, "add_aux_variable");
19registerMooseAction("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");
52}
53
54void
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
80void
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
98void
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
123void
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);
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
170void
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
205void
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
221void
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
245void
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
261void
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
308void
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
384 "energy_wall_types", _energy_wall_types[bc_ind], " wall type is currently unsupported.");
385 }
386}
387
388void
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
408void
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;
424 params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
425
427 {
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}
const ExecFlagType EXEC_NONLINEAR
registerNavierStokesPhysicsBaseTasks("NavierStokesApp", WCNSLinearFVFluidHeatTransferPhysics)
registerMooseAction("NavierStokesApp", WCNSLinearFVFluidHeatTransferPhysics, "add_aux_variable")
registerWCNSFVFluidHeatTransferPhysicsBaseTasks("NavierStokesApp", WCNSLinearFVFluidHeatTransferPhysics)
virtual void addLinearFVKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
virtual void addMaterial(const std::string &material_name, const std::string &name, InputParameters &parameters)
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
virtual void addAuxKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
virtual void addLinearFVBC(const std::string &fv_bc_name, const std::string &name, InputParameters &parameters)
virtual void addAuxVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
InputParameters getValidParams(const std::string &name) const
void checkSecondParamSetOnlyIfFirstOneTrue(const std::string &param1, const std::string &param2) const
void suppressParameter(const std::string &name)
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
void paramError(const std::string &param, Args... args) const
bool isParamSetByUser(const std::string &name) const
bool isParamValid(const std::string &name) const
unsigned int size() const
bool _define_variables
Whether to define variables if they do not exist.
virtual FEProblemBase & getProblem()
Factory & getFactory()
bool checkBlockRestrictionIdentical(const std::string &object_name, const std::vector< SubdomainName > &blocks, const bool error_if_not_identical=true) const
void assignBlocks(InputParameters &params, 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
std::string prefix() const
bool variableExists(const VariableName &var_name, bool error_if_aux) const
const SolverSystemName & getSolverSystem(unsigned int variable_index) const
bool shouldCreateVariable(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool error_if_aux)
std::vector< SubdomainName > _blocks
const std::vector< SubdomainName > & blocks() const
const WCNSFVFlowPhysicsBase * _flow_equations_physics
Flow physics.
bool _has_turbulence_model
Because of the Modules/navierStokesFV syntax, a turbulence physics often exists without a model we sa...
const bool _porous_medium_treatment
Switch to show if porous medium treatment is requested or not.
const MooseFunctorName _density_name
Name of the density material property.
const NonlinearVariableName & getPressureName() const
const std::vector< BoundaryName > & getWallBoundaries() const
Get the wall boundaries.
const UserObjectName & rhieChowUOName() const
Return the name of the Rhie Chow user object.
const std::vector< BoundaryName > & getOutletBoundaries() const
Get the outlet boundaries.
const std::vector< BoundaryName > & getInletBoundaries() const
Get the inlet boundaries.
Creates all the objects needed to solve the Navier Stokes energy equation.
std::vector< MooseFunctorName > _energy_inlet_functors
Functors describing the inlet boundary values. See energy_inlet_types for what the functors actually ...
std::vector< MooseFunctorName > _energy_wall_functors
Functors describing the wall boundary values. See energy_wall_types for what the functors actually re...
MooseFunctorName _specific_heat_name
Name of the specific heat material property.
std::vector< MooseFunctorName > _ambient_convection_alpha
Name of the ambient convection heat transfer coefficients for each block-group.
const VariableName _fluid_enthalpy_name
Name of the fluid specific enthalpy.
bool processThermalConductivity()
Process thermal conductivity (multiple functor input options are available).
std::vector< std::vector< SubdomainName > > _ambient_convection_blocks
Vector of subdomain groups where we want to have different ambient convection.
VariableName _fluid_temperature_name
Fluid temperature name.
void defineEffectiveThermalDiffusionCoeffFunctors(const bool use_ad)
Define the effective diffusion coefficient when:
const bool _has_energy_equation
A boolean to help compatibility with the old Modules/NavierStokesFV syntax.
const bool _solve_for_enthalpy
User-selected option to solve for enthalpy.
std::vector< MooseFunctorName > _thermal_conductivity_name
Name of the thermal conductivity functor for each block-group.
std::vector< std::vector< SubdomainName > > _thermal_conductivity_blocks
Vector of subdomain groups where we want to have different thermal conduction.
MultiMooseEnum _energy_wall_types
Energy wall boundary types.
MultiMooseEnum _energy_inlet_types
Energy inlet boundary types.
std::vector< MooseFunctorName > _ambient_temperature
Name of the solid domain temperature for each block-group.
Creates all the objects needed to solve the Navier Stokes energy equation using a linear finite volum...
void addEnergyInletBC() override
Functions adding boundary conditions for the incompressible / weakly compressible energy equation.
void addEnergyTimeKernels() override
Functions adding kernels for the incompressible / weakly compressible energy equation.
WCNSLinearFVFluidHeatTransferPhysics(const InputParameters &parameters)
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count)
std::string stringify(const T &t)
static const std::string T_fluid
Definition NS.h:110
static const std::string T_solid
Definition NS.h:111
static const std::string specific_enthalpy
Definition NS.h:69
static const std::string fluid
Definition NS.h:88
static const std::string pressure
Definition NS.h:57