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