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", "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 addSharedSolverVariable(var_type, variable_name, params);
71 }
72 else
73 paramError(_solve_for_enthalpy ? "solve_for_enthalpy" : "fluid_temperature_variable",
74 "Variable (" + variable_name +
75 ") supplied to the WCNSLinearFVFluidHeatTransferPhysics does not exist!");
76}
77
78void
80{
81 std::string kernel_type = "LinearFVTimeDerivative";
82 std::string kernel_name = prefix() + "ins_energy_time";
83
84 InputParameters params = getFactory().getValidParams(kernel_type);
85 params.set<LinearVariableName>("variable") =
87 assignBlocks(params, _blocks);
89 params.set<MooseFunctorName>("factor") = "rho_cp";
90 else
91 params.set<MooseFunctorName>("factor") = _density_name;
92
93 getProblem().addLinearFVKernel(kernel_type, kernel_name, params);
94}
95
96void
98{
99 std::string kernel_type = "LinearFVEnergyAdvection";
100 std::string kernel_name = prefix() + "ins_energy_advection";
101
102 InputParameters params = getFactory().getValidParams(kernel_type);
103 assignBlocks(params, _blocks);
104 if (!getParam<bool>("solve_for_enthalpy"))
105 {
106 params.set<LinearVariableName>("variable") = _fluid_temperature_name;
107 params.set<MooseEnum>("advected_quantity") = "temperature";
108 if (!MooseUtils::isFloat(_specific_heat_name))
109 paramError("specific_heat", "Must be a Real number. Functors not supported at this time");
110 params.set<Real>("cp") = std::atof(_specific_heat_name.c_str());
111 }
112 else
113 params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
114 params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName();
115 params.set<MooseEnum>("advected_interp_method") =
116 getParam<MooseEnum>("energy_advection_interpolation");
117
118 getProblem().addLinearFVKernel(kernel_type, kernel_name, params);
119}
120
121void
123{
124 const auto num_blocks = _thermal_conductivity_blocks.size();
125 const auto num_used_blocks = num_blocks ? num_blocks : 1;
126
127 for (const auto block_i : make_range(num_used_blocks))
128 {
129 std::string block_name = "";
130 if (num_blocks)
131 block_name = Moose::stringify(_thermal_conductivity_blocks[block_i]);
132 else
133 block_name = "all";
134
135 const std::string kernel_type = "LinearFVDiffusion";
136 InputParameters params = getFactory().getValidParams(kernel_type);
138 {
139 params.set<LinearVariableName>("variable") = _fluid_temperature_name;
141 params.set<MooseFunctorName>("diffusion_coeff") = _thermal_conductivity_name[block_i];
142 else
143 params.set<MooseFunctorName>("diffusion_coeff") = NS::k_eff_t;
144 }
145 else
146 {
147 params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
148 const auto th_cond_name =
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);
236 }
237 else
238 paramError("fluid_temperature_variable",
239 "Variable (" + _fluid_temperature_name +
240 ") supplied to the WCNSLinearFVFluidHeatTransferPhysics does not exist!");
241 }
242}
243
244void
246{
248 {
249 // Keep temperature updated
250 const std::string kernel_type = "FunctorAux";
251 InputParameters params = getFactory().getValidParams(kernel_type);
252 params.set<AuxVariableName>("variable") = _fluid_temperature_name;
253 assignBlocks(params, _blocks);
254 params.set<MooseFunctorName>("functor") = "T_from_p_h";
255 params.set<ExecFlagEnum>("execute_on") = {EXEC_NONLINEAR};
256 getProblem().addAuxKernel(kernel_type, prefix() + "update_temperature", params);
257 }
258}
259
260void
262{
263 const auto & inlet_boundaries = _flow_equations_physics->getInletBoundaries();
264 // These are parameter errors for now. If Components add boundaries to Physics, the error
265 // may not be due to parameters anymore.
266 if (inlet_boundaries.size() != _energy_inlet_types.size())
267 paramError("energy_inlet_types",
268 "Energy inlet types (size " + std::to_string(_energy_inlet_types.size()) +
269 ") should be the same size as inlet_boundaries (size " +
270 std::to_string(inlet_boundaries.size()) + ")");
271 if (inlet_boundaries.size() != _energy_inlet_functors.size())
272 paramError("energy_inlet_functors",
273 "Energy inlet functors (size " + std::to_string(_energy_inlet_functors.size()) +
274 ") should be the same size as inlet_boundaries (size " +
275 std::to_string(inlet_boundaries.size()) + ")");
276
277 for (const auto bc_ind : index_range(_energy_inlet_types))
278 {
279 if (_energy_inlet_types[bc_ind] == "fixed-temperature")
280 {
281 const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
282 InputParameters params = getFactory().getValidParams(bc_type);
283 params.set<LinearVariableName>("variable") = _fluid_temperature_name;
284 params.set<MooseFunctorName>("functor") = _energy_inlet_functors[bc_ind];
285 params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]};
286
288 bc_type, _fluid_temperature_name + "_" + inlet_boundaries[bc_ind], params);
289
290 // Boundary condition on temperature must be forwarded to enthalpy
292 {
293 params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
294 params.set<MooseFunctorName>("functor") = "h_from_p_T";
296 bc_type, _fluid_enthalpy_name + "_" + inlet_boundaries[bc_ind], params);
297 }
298 }
299 else if (_energy_inlet_types[bc_ind] == "heatflux")
300 paramError("energy_inlet_types", "Heat flux inlet boundary conditions not yet supported");
301 else if (_energy_inlet_types[bc_ind] == "flux-mass" ||
302 _energy_inlet_types[bc_ind] == "flux-velocity")
303 paramError("energy_inlet_types", "Flux inlet boundary conditions not yet supported");
304 }
305}
306
307void
309{
310 const auto & wall_boundaries = isParamSetByUser("energy_wall_boundaries")
311 ? getParam<std::vector<BoundaryName>>("energy_wall_boundaries")
313 if (wall_boundaries.size() != _energy_wall_types.size())
314 paramError("energy_wall_types",
315 "Energy wall types (size " + std::to_string(_energy_wall_types.size()) +
316 ") should be the same size as wall_boundaries (size " +
317 std::to_string(wall_boundaries.size()) + ")");
318 if (wall_boundaries.size() != _energy_wall_functors.size())
319 paramError("energy_wall_functors",
320 "Energy wall functors (size " + std::to_string(_energy_wall_functors.size()) +
321 ") should be the same size as wall_boundaries (size " +
322 std::to_string(wall_boundaries.size()) + ")");
323
324 for (unsigned int bc_ind = 0; bc_ind < _energy_wall_types.size(); ++bc_ind)
325 {
326 if (_energy_wall_types[bc_ind] == "fixed-temperature")
327 {
328 const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
329 InputParameters params = getFactory().getValidParams(bc_type);
330 params.set<LinearVariableName>("variable") = _fluid_temperature_name;
331 params.set<MooseFunctorName>("functor") = _energy_wall_functors[bc_ind];
332 params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
333
335 bc_type, _fluid_temperature_name + "_" + wall_boundaries[bc_ind], params);
336
337 // Boundary condition on temperature must be forwarded to enthalpy
339 {
340 params.set<LinearVariableName>("variable") = _fluid_enthalpy_name;
341 params.set<MooseFunctorName>("functor") = "h_from_p_T";
343 bc_type, _fluid_enthalpy_name + "_" + wall_boundaries[bc_ind], params);
344 }
345 }
346 else if (_energy_wall_types[bc_ind] == "heatflux")
347 {
348 const std::string bc_type = "LinearFVAdvectionDiffusionFunctorNeumannBC";
349 InputParameters params = getFactory().getValidParams(bc_type);
351 params.set<LinearVariableName>("variable") = var_name;
352 params.set<MooseFunctorName>("functor") = _energy_wall_functors[bc_ind];
353 params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
354
356 bc_type, var_name + "_heatflux_" + wall_boundaries[bc_ind], params);
357 }
358 else if (_energy_wall_types[bc_ind] == "convection")
359 {
360 const std::string bc_type = "LinearFVConvectiveHeatTransferBC";
361 InputParameters params = getFactory().getValidParams(bc_type);
362 params.set<LinearVariableName>("variable") =
364 params.set<MooseFunctorName>(NS::T_fluid) = _fluid_temperature_name;
365 const auto Tinf_htc_functors =
366 MooseUtils::split(_energy_wall_functors[bc_ind], /*delimiter=*/":", /*max_count=*/1);
367 if (Tinf_htc_functors.size() != 2)
368 paramError("energy_wall_functors",
369 "'convection' wall types require two functors specified as "
370 "<Tinf_functor>:<htc_functor>.");
371 params.set<MooseFunctorName>(NS::T_solid) = Tinf_htc_functors[0];
372 params.set<MooseFunctorName>("h") = Tinf_htc_functors[1];
373 params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
374
376 bc_type,
378 wall_boundaries[bc_ind],
379 params);
380 }
381 else
383 "energy_wall_types", _energy_wall_types[bc_ind], " wall type is currently unsupported.");
384 }
385}
386
387void
389{
390 const auto & outlet_boundaries = _flow_equations_physics->getOutletBoundaries();
391 if (outlet_boundaries.empty())
392 return;
393
394 for (const auto & outlet_bdy : outlet_boundaries)
395 {
396 const std::string bc_type = "LinearFVAdvectionDiffusionOutflowBC";
398 InputParameters params = getFactory().getValidParams(bc_type);
399 params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
400 params.set<bool>("use_two_term_expansion") = getParam<bool>("energy_two_term_bc_expansion");
401
402 params.set<LinearVariableName>("variable") = variable_name;
403 getProblem().addLinearFVBC(bc_type, variable_name + "_" + outlet_bdy, params);
404 }
405}
406
407void
409{
410 // For compatibility with Modules/NavierStokesFV syntax
412 return;
413
414 // Note that this material choice would not work for Newton-INSFV + solve_for_enthalpy
415 const auto object_type = "LinearFVEnthalpyFunctorMaterial";
416
417 InputParameters params = getFactory().getValidParams(object_type);
418 assignBlocks(params, _blocks);
419 params.set<MooseFunctorName>(NS::pressure) = _flow_equations_physics->getPressureName();
420 params.set<MooseFunctorName>(NS::T_fluid) = _fluid_temperature_name;
421 params.set<MooseFunctorName>(NS::specific_enthalpy) = _fluid_enthalpy_name;
423 params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
424
426 {
428 {
429 if (!getProblem().hasFunctor("h_from_p_T_functor", 0) ||
430 !getProblem().hasFunctor("T_from_p_h_functor", 0))
432 "Either 'fp' must be specified or the 'h_from_p_T_functor' and "
433 "'T_from_p_h_functor' must be defined outside the Physics");
434 // Note: we could define those in the Physics if cp is constant
435 params.set<MooseFunctorName>("h_from_p_T_functor") = "h_from_p_T_functor";
436 params.set<MooseFunctorName>("T_from_p_h_functor") = "T_from_p_h_functor";
437 }
438 }
439 // If we are solving for enthalpy, we need this to compute temperature from p & h
440 // Else we don't really need it
442 getProblem().addMaterial(object_type, prefix() + "enthalpy_material", params);
443
446 /*use ad*/ false);
447}
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 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)
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.
void addSharedAuxVariable(const std::string &var_type, const VariableName &var_name, const InputParameters &params)
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
void addSharedSolverVariable(const std::string &var_type, const VariableName &var_name, InputParameters params)
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 k_eff_t
Definition NS.h:137
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