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 "WCNSFVFluidHeatTransferPhysics.h"
11 : #include "WCNSFVFlowPhysics.h"
12 : #include "NSFVBase.h"
13 : #include "NS.h"
14 :
15 : registerNavierStokesPhysicsBaseTasks("NavierStokesApp", WCNSFVFluidHeatTransferPhysics);
16 : registerWCNSFVFluidHeatTransferPhysicsBaseTasks("NavierStokesApp", WCNSFVFluidHeatTransferPhysics);
17 :
18 : InputParameters
19 709 : WCNSFVFluidHeatTransferPhysics::validParams()
20 : {
21 709 : InputParameters params = WCNSFVFluidHeatTransferPhysicsBase::validParams();
22 709 : params.transferParam<MooseEnum>(NSFVBase::validParams(), "energy_face_interpolation");
23 709 : params.transferParam<Real>(NSFVBase::validParams(), "energy_scaling");
24 1418 : params.addParam<bool>(
25 : "check_bc_compatibility",
26 1418 : true,
27 : "Whether to check for known incompatibility between boundary conditions for "
28 : "the heat transport equation physics and other physics");
29 1418 : params.addParamNamesToGroup("check_bc_compatibility", "Advanced");
30 :
31 1418 : params.addParamNamesToGroup("energy_face_interpolation energy_scaling", "Numerical scheme");
32 709 : return params;
33 0 : }
34 :
35 709 : WCNSFVFluidHeatTransferPhysics::WCNSFVFluidHeatTransferPhysics(const InputParameters & parameters)
36 709 : : WCNSFVFluidHeatTransferPhysicsBase(parameters)
37 : {
38 1414 : checkSecondParamNotSetIfFirstOneSet("solve_for_enthalpy", "fluid_temperature_variable");
39 707 : }
40 :
41 : void
42 683 : WCNSFVFluidHeatTransferPhysics::addSolverVariables()
43 : {
44 : // For compatibility with Modules/NavierStokesFV syntax
45 683 : if (!_has_energy_equation)
46 : return;
47 :
48 : const auto & solver_variable_name =
49 398 : _solve_for_enthalpy ? _fluid_enthalpy_name : _fluid_temperature_name;
50 :
51 : // Dont add if the user already defined the variable
52 398 : if (!shouldCreateVariable(solver_variable_name, _blocks, /*error if aux*/ true))
53 17 : reportPotentiallyMissedParameters({"system_names",
54 : "energy_scaling",
55 : "energy_face_interpolation",
56 : "energy_two_term_bc_expansion"},
57 : "INSFVEnergyVariable");
58 381 : else if (_define_variables)
59 : {
60 379 : auto params = getFactory().getValidParams("INSFVEnergyVariable");
61 379 : assignBlocks(params, _blocks);
62 1137 : params.set<std::vector<Real>>("scaling") = {getParam<Real>("energy_scaling")};
63 1137 : params.set<MooseEnum>("face_interp_method") = getParam<MooseEnum>("energy_face_interpolation");
64 379 : params.set<bool>("two_term_boundary_expansion") =
65 758 : getParam<bool>("energy_two_term_bc_expansion");
66 758 : params.set<SolverSystemName>("solver_sys") = getSolverSystem(solver_variable_name);
67 379 : getProblem().addVariable("INSFVEnergyVariable", solver_variable_name, params);
68 379 : }
69 : else
70 : // we don't let the user select the enthalpy variable name at this time
71 4 : paramError(_solve_for_enthalpy ? "solve_for_enthalpy" : "fluid_temperature_variable",
72 2 : "Variable (" + solver_variable_name +
73 : ") supplied to the WCNSFVFluidHeatTransferPhysics does not exist!");
74 : }
75 :
76 : void
77 108 : WCNSFVFluidHeatTransferPhysics::addEnergyTimeKernels()
78 : {
79 : std::string kernel_type =
80 108 : ((_compressibility == "weakly-compressible") ? "WCNSFVEnergyTimeDerivative"
81 144 : : "INSFVEnergyTimeDerivative");
82 : std::string kernel_name =
83 108 : prefix() + ((_compressibility == "weakly-compressible") ? "wcns" : "ins") + "_energy_time";
84 108 : if (_porous_medium_treatment)
85 : {
86 : kernel_type = "PINSFVEnergyTimeDerivative";
87 96 : kernel_name = prefix() + ((_compressibility == "weakly-compressible") ? "pwcns" : "pins") +
88 48 : "_energy_time";
89 : }
90 :
91 : const auto & solver_variable_name =
92 108 : _solve_for_enthalpy ? _fluid_enthalpy_name : _fluid_temperature_name;
93 :
94 108 : InputParameters params = getFactory().getValidParams(kernel_type);
95 108 : assignBlocks(params, _blocks);
96 216 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
97 108 : params.set<MooseFunctorName>(NS::density) = _density_name;
98 216 : params.set<MooseFunctorName>(NS::time_deriv(NS::specific_enthalpy)) =
99 108 : NS::time_deriv(NS::specific_enthalpy);
100 108 : if (_compressibility == "weakly-compressible")
101 : {
102 288 : params.set<MooseFunctorName>(NS::time_deriv(NS::density)) = NS::time_deriv(_density_name);
103 144 : params.set<MooseFunctorName>(NS::specific_enthalpy) = NS::specific_enthalpy;
104 : }
105 108 : if (_porous_medium_treatment)
106 : {
107 48 : params.set<MooseFunctorName>(NS::porosity) =
108 96 : _flow_equations_physics->getPorosityFunctorName(/*smoothed=*/false);
109 96 : if (getProblem().hasFunctor(NS::time_deriv(_density_name),
110 : /*thread_id=*/0))
111 : {
112 192 : params.set<MooseFunctorName>(NS::time_deriv(NS::density)) = NS::time_deriv(_density_name);
113 96 : params.set<MooseFunctorName>(NS::specific_enthalpy) = NS::specific_enthalpy;
114 : }
115 :
116 48 : params.set<bool>("is_solid") = false;
117 : }
118 :
119 108 : getProblem().addFVKernel(kernel_type, kernel_name, params);
120 216 : }
121 :
122 : void
123 386 : WCNSFVFluidHeatTransferPhysics::addEnergyAdvectionKernels()
124 : {
125 386 : std::string kernel_type = "INSFVEnergyAdvection";
126 0 : std::string kernel_name = prefix() + "ins_energy_advection";
127 386 : if (_porous_medium_treatment)
128 : {
129 : kernel_type = "PINSFVEnergyAdvection";
130 226 : kernel_name = prefix() + "pins_energy_advection";
131 : }
132 :
133 : const auto & solver_variable_name =
134 386 : _solve_for_enthalpy ? _fluid_enthalpy_name : _fluid_temperature_name;
135 :
136 386 : InputParameters params = getFactory().getValidParams(kernel_type);
137 772 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
138 386 : assignBlocks(params, _blocks);
139 386 : params.set<MooseEnum>("velocity_interp_method") = _velocity_interpolation;
140 386 : params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName();
141 772 : params.set<MooseEnum>("advected_interp_method") =
142 1158 : getParam<MooseEnum>("energy_advection_interpolation");
143 :
144 386 : getProblem().addFVKernel(kernel_type, kernel_name, params);
145 772 : }
146 :
147 : void
148 386 : WCNSFVFluidHeatTransferPhysics::addEnergyHeatConductionKernels()
149 : {
150 386 : const auto vector_conductivity = processThermalConductivity();
151 : const auto num_blocks = _thermal_conductivity_blocks.size();
152 : const auto num_used_blocks = num_blocks ? num_blocks : 1;
153 : const auto & solver_variable_name =
154 380 : _solve_for_enthalpy ? _fluid_enthalpy_name : _fluid_temperature_name;
155 :
156 769 : for (const auto block_i : make_range(num_used_blocks))
157 : {
158 389 : std::string block_name = "";
159 389 : if (num_blocks)
160 36 : block_name = Moose::stringify(_thermal_conductivity_blocks[block_i]);
161 : else
162 : block_name = "all";
163 :
164 389 : if (_porous_medium_treatment)
165 : {
166 : const auto kernel_type =
167 120 : vector_conductivity ? "PINSFVEnergyAnisotropicDiffusion" : "PINSFVEnergyDiffusion";
168 :
169 120 : InputParameters params = getFactory().getValidParams(kernel_type);
170 240 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
171 138 : const auto block_names = num_blocks ? _thermal_conductivity_blocks[block_i] : _blocks;
172 120 : assignBlocks(params, block_names);
173 222 : const auto conductivity_name = vector_conductivity ? NS::kappa : NS::k;
174 120 : params.set<MooseFunctorName>(NS::porosity) =
175 120 : _flow_equations_physics->getPorosityFunctorName(true);
176 240 : params.set<bool>("effective_conductivity") = getParam<bool>("effective_conductivity");
177 120 : if (!_solve_for_enthalpy)
178 120 : params.set<MooseFunctorName>(conductivity_name) = _thermal_conductivity_name[block_i];
179 : else
180 0 : params.set<MooseFunctorName>(conductivity_name) =
181 0 : _thermal_conductivity_name[block_i] + "_by_cp";
182 :
183 360 : getProblem().addFVKernel(
184 240 : kernel_type, prefix() + "pins_energy_diffusion_" + block_name, params);
185 120 : }
186 : else
187 : {
188 269 : const std::string kernel_type = "FVDiffusion";
189 269 : InputParameters params = getFactory().getValidParams(kernel_type);
190 538 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
191 : std::vector<SubdomainName> block_names =
192 269 : num_blocks ? _thermal_conductivity_blocks[block_i] : _blocks;
193 269 : assignBlocks(params, block_names);
194 269 : if (!_solve_for_enthalpy)
195 484 : params.set<MooseFunctorName>("coeff") = _thermal_conductivity_name[block_i];
196 : else
197 108 : params.set<MooseFunctorName>("coeff") = _thermal_conductivity_name[block_i] + "_by_cp";
198 :
199 538 : getProblem().addFVKernel(
200 269 : kernel_type, prefix() + "ins_energy_diffusion_" + block_name, params);
201 269 : }
202 : }
203 380 : }
204 :
205 : void
206 119 : WCNSFVFluidHeatTransferPhysics::addEnergyAmbientConvection()
207 : {
208 119 : unsigned int num_convection_blocks = _ambient_convection_blocks.size();
209 : unsigned int num_used_blocks = num_convection_blocks ? num_convection_blocks : 1;
210 : const auto & solver_variable_name =
211 119 : _solve_for_enthalpy ? _fluid_enthalpy_name : _fluid_temperature_name;
212 :
213 119 : const std::string kernel_type = "PINSFVEnergyAmbientConvection";
214 119 : InputParameters params = getFactory().getValidParams(kernel_type);
215 238 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
216 119 : params.set<MooseFunctorName>(NS::T_fluid) = _fluid_temperature_name;
217 119 : params.set<bool>("is_solid") = false;
218 :
219 238 : for (unsigned int block_i = 0; block_i < num_used_blocks; ++block_i)
220 : {
221 119 : std::string block_name = "";
222 119 : if (num_convection_blocks)
223 : {
224 9 : params.set<std::vector<SubdomainName>>("block") = _ambient_convection_blocks[block_i];
225 18 : block_name = Moose::stringify(_ambient_convection_blocks[block_i]);
226 : }
227 : else
228 : {
229 110 : assignBlocks(params, _blocks);
230 220 : block_name = std::to_string(block_i);
231 : }
232 :
233 238 : params.set<MooseFunctorName>("h_solid_fluid") = _ambient_convection_alpha[block_i];
234 119 : params.set<MooseFunctorName>(NS::T_solid) = _ambient_temperature[block_i];
235 :
236 357 : getProblem().addFVKernel(kernel_type, prefix() + "ambient_convection_" + block_name, params);
237 : }
238 238 : }
239 :
240 : void
241 104 : WCNSFVFluidHeatTransferPhysics::addEnergyExternalHeatSource()
242 : {
243 : const auto & solver_variable_name =
244 104 : _solve_for_enthalpy ? _fluid_enthalpy_name : _fluid_temperature_name;
245 104 : const std::string kernel_type = "FVCoupledForce";
246 104 : InputParameters params = getFactory().getValidParams(kernel_type);
247 208 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
248 104 : assignBlocks(params, _blocks);
249 312 : params.set<MooseFunctorName>("v") = getParam<MooseFunctorName>("external_heat_source");
250 208 : params.set<Real>("coef") = getParam<Real>("external_heat_source_coeff");
251 :
252 208 : getProblem().addFVKernel(kernel_type, prefix() + "external_heat_source", params);
253 208 : }
254 :
255 : void
256 376 : WCNSFVFluidHeatTransferPhysics::addEnergyInletBC()
257 : {
258 376 : const auto & inlet_boundaries = _flow_equations_physics->getInletBoundaries();
259 : // These are parameter errors for now. If Components add boundaries to Physics, the error
260 : // may not be due to parameters anymore.
261 376 : if (inlet_boundaries.size() != _energy_inlet_types.size())
262 4 : paramError("energy_inlet_types",
263 2 : "Energy inlet types (size " + std::to_string(_energy_inlet_types.size()) +
264 2 : ") should be the same size as inlet_boundaries (size " +
265 2 : std::to_string(inlet_boundaries.size()) + ")");
266 374 : if (inlet_boundaries.size() != _energy_inlet_functors.size())
267 0 : paramError("energy_inlet_functors",
268 0 : "Energy inlet functors (size " + std::to_string(_energy_inlet_functors.size()) +
269 0 : ") should be the same size as inlet_boundaries (size " +
270 0 : std::to_string(inlet_boundaries.size()) + ")");
271 :
272 : const auto & solver_variable_name =
273 374 : _solve_for_enthalpy ? _fluid_enthalpy_name : _fluid_temperature_name;
274 :
275 : unsigned int flux_bc_counter = 0;
276 733 : for (const auto bc_ind : index_range(_energy_inlet_types))
277 : {
278 359 : if (_energy_inlet_types[bc_ind] == "fixed-temperature")
279 : {
280 204 : const std::string bc_type = _solve_for_enthalpy
281 : ? "FVSpecificEnthalpyFromPressureTemperatureDirichletBC"
282 399 : : "FVADFunctorDirichletBC";
283 204 : InputParameters params = getFactory().getValidParams(bc_type);
284 408 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
285 204 : if (!_solve_for_enthalpy)
286 390 : params.set<MooseFunctorName>("functor") = _energy_inlet_functors[bc_ind];
287 : else
288 : {
289 : mooseAssert(_flow_equations_physics, "Should be coupled");
290 9 : params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
291 9 : params.set<MooseFunctorName>(NS::pressure) = _flow_equations_physics->getPressureName();
292 9 : params.set<MooseFunctorName>(NS::T_fluid) = _energy_inlet_functors[bc_ind];
293 : }
294 612 : params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]};
295 :
296 204 : getProblem().addFVBC(bc_type, solver_variable_name + "_" + inlet_boundaries[bc_ind], params);
297 :
298 : // Check the BCs for momentum
299 : const auto momentum_inlet_type =
300 204 : _flow_equations_physics->inletBoundaryType(inlet_boundaries[bc_ind]);
301 612 : if (getParam<bool>("check_bc_compatibility") &&
302 204 : (momentum_inlet_type == NS::MomentumInletTypes::FLUX_VELOCITY ||
303 : momentum_inlet_type == NS::MomentumInletTypes::FLUX_MASS))
304 0 : paramError("energy_inlet_types",
305 0 : "At inlet '" + inlet_boundaries[bc_ind] +
306 : "', you are using a Dirichlet boundary condition on temperature, and a "
307 : "flux boundary condition on momentum. This is known to create an "
308 : "undesirable inlet source term.");
309 204 : }
310 155 : else if (_energy_inlet_types[bc_ind] == "heatflux")
311 : {
312 88 : const std::string bc_type = "FVFunctionNeumannBC";
313 88 : InputParameters params = getFactory().getValidParams(bc_type);
314 176 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
315 176 : params.set<FunctionName>("function") = _energy_inlet_functors[bc_ind];
316 264 : params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]};
317 :
318 88 : getProblem().addFVBC(bc_type, solver_variable_name + "_" + inlet_boundaries[bc_ind], params);
319 88 : }
320 67 : else if (_energy_inlet_types[bc_ind] == "flux-mass" ||
321 39 : _energy_inlet_types[bc_ind] == "flux-velocity")
322 : {
323 67 : const std::string bc_type = "WCNSFVEnergyFluxBC";
324 67 : InputParameters params = getFactory().getValidParams(bc_type);
325 134 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
326 67 : const auto & flux_inlet_directions = _flow_equations_physics->getFluxInletDirections();
327 : const auto & flux_inlet_pps = _flow_equations_physics->getFluxInletPPs();
328 :
329 67 : if (flux_inlet_pps.size() < flux_bc_counter)
330 0 : _flow_equations_physics->paramError(
331 : "flux_inlet_pps",
332 : "Should be specified for all 'flux-mass/velocity' boundary conditions");
333 :
334 67 : if (flux_inlet_directions.size())
335 : {
336 14 : if (flux_inlet_directions.size() < flux_bc_counter)
337 0 : _flow_equations_physics->paramError("flux_inlet_pps",
338 : "Should be specified for all or none of the "
339 : "'flux-mass/velocity' boundary conditions");
340 14 : params.set<Point>("direction") = flux_inlet_directions[flux_bc_counter];
341 : }
342 67 : if (_energy_inlet_types[bc_ind] == "flux-mass")
343 : {
344 28 : params.set<PostprocessorName>("mdot_pp") = flux_inlet_pps[flux_bc_counter];
345 112 : params.set<PostprocessorName>("area_pp") = "area_pp_" + inlet_boundaries[bc_ind];
346 : }
347 : else
348 78 : params.set<PostprocessorName>("velocity_pp") = flux_inlet_pps[flux_bc_counter];
349 :
350 134 : params.set<PostprocessorName>("temperature_pp") = _energy_inlet_functors[bc_ind];
351 67 : params.set<MooseFunctorName>(NS::density) = _density_name;
352 67 : params.set<MooseFunctorName>(NS::cp) = _specific_heat_name;
353 134 : params.set<MooseFunctorName>(NS::T_fluid) = _fluid_temperature_name;
354 :
355 67 : if (isParamValid(NS::fluid))
356 : {
357 18 : params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
358 36 : params.set<MooseFunctorName>(NS::pressure) = _flow_equations_physics->getPressureName();
359 : }
360 :
361 67 : if (_solve_for_enthalpy)
362 36 : params.set<MooseFunctorName>(NS::specific_enthalpy) = _fluid_enthalpy_name;
363 :
364 192 : for (const auto d : make_range(dimension()))
365 250 : params.set<MooseFunctorName>(NS::velocity_vector[d]) = _velocity_names[d];
366 :
367 201 : params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]};
368 :
369 67 : getProblem().addFVBC(bc_type, solver_variable_name + "_" + inlet_boundaries[bc_ind], params);
370 67 : flux_bc_counter += 1;
371 67 : }
372 : }
373 374 : }
374 :
375 : void
376 374 : WCNSFVFluidHeatTransferPhysics::addEnergyWallBC()
377 : {
378 748 : const auto & wall_boundaries = isParamSetByUser("energy_wall_boundaries")
379 766 : ? getParam<std::vector<BoundaryName>>("energy_wall_boundaries")
380 356 : : _flow_equations_physics->getWallBoundaries();
381 374 : if (wall_boundaries.size() != _energy_wall_types.size())
382 4 : paramError("energy_wall_types",
383 2 : "Energy wall types (size " + std::to_string(_energy_wall_types.size()) +
384 2 : ") should be the same size as wall_boundaries (size " +
385 2 : std::to_string(wall_boundaries.size()) + ")");
386 372 : if (wall_boundaries.size() != _energy_wall_functors.size())
387 0 : paramError("energy_wall_functors",
388 0 : "Energy wall functors (size " + std::to_string(_energy_wall_functors.size()) +
389 0 : ") should be the same size as wall_boundaries (size " +
390 0 : std::to_string(wall_boundaries.size()) + ")");
391 :
392 : const auto & solver_variable_name =
393 372 : _solve_for_enthalpy ? _fluid_enthalpy_name : _fluid_temperature_name;
394 :
395 1162 : for (unsigned int bc_ind = 0; bc_ind < _energy_wall_types.size(); ++bc_ind)
396 : {
397 790 : if (_energy_wall_types[bc_ind] == "fixed-temperature")
398 : {
399 86 : const std::string bc_type = _solve_for_enthalpy
400 : ? "FVSpecificEnthalpyFromPressureTemperatureDirichletBC"
401 136 : : "FVADFunctorDirichletBC";
402 86 : InputParameters params = getFactory().getValidParams(bc_type);
403 172 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
404 86 : if (!_solve_for_enthalpy)
405 100 : params.set<MooseFunctorName>("functor") = _energy_wall_functors[bc_ind];
406 : else
407 : {
408 36 : params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
409 36 : params.set<MooseFunctorName>(NS::pressure) = _flow_equations_physics->getPressureName();
410 36 : params.set<MooseFunctorName>(NS::T_fluid) = _energy_wall_functors[bc_ind];
411 : }
412 258 : params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
413 :
414 86 : getProblem().addFVBC(bc_type, solver_variable_name + "_" + wall_boundaries[bc_ind], params);
415 86 : }
416 704 : else if (_energy_wall_types[bc_ind] == "heatflux")
417 : {
418 674 : const std::string bc_type = "FVFunctorNeumannBC";
419 674 : InputParameters params = getFactory().getValidParams(bc_type);
420 1348 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
421 1348 : params.set<MooseFunctorName>("functor") = _energy_wall_functors[bc_ind];
422 2022 : params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
423 :
424 674 : getProblem().addFVBC(bc_type, solver_variable_name + "_" + wall_boundaries[bc_ind], params);
425 674 : }
426 30 : else if (_energy_wall_types[bc_ind] == "convection")
427 : {
428 0 : const std::string bc_type = "FVFunctorConvectiveHeatFluxBC";
429 0 : InputParameters params = getFactory().getValidParams(bc_type);
430 0 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
431 0 : params.set<MooseFunctorName>("T_bulk") = _fluid_temperature_name;
432 0 : params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
433 0 : params.set<bool>("is_solid") = false;
434 : const auto Tinf_htc_functors =
435 0 : MooseUtils::split(_energy_wall_functors[bc_ind], /*delimiter=*/":", /*max_count=*/1);
436 0 : if (Tinf_htc_functors.size() != 2)
437 0 : paramError("energy_wall_functors",
438 : "'convective' wall types require two functors specified as "
439 : "<Tinf_functor>:<htc_functor>.");
440 0 : params.set<MooseFunctorName>("T_solid") = Tinf_htc_functors[0];
441 0 : params.set<MooseFunctorName>("heat_transfer_coefficient") = Tinf_htc_functors[1];
442 :
443 0 : getProblem().addFVBC(bc_type, solver_variable_name + "_" + wall_boundaries[bc_ind], params);
444 0 : }
445 : // We add this boundary condition here to facilitate the input of wall boundaries / functors for
446 : // energy. If there are too many turbulence options and this gets out of hand we will have to
447 : // move this to the turbulence Physics
448 30 : else if (_energy_wall_types[bc_ind] == "wallfunction")
449 : {
450 30 : if (!_turbulence_physics)
451 0 : paramError("coupled_turbulence_physics",
452 : "A coupled turbulence Physics was not found for defining the wall function "
453 0 : "boundary condition on boundary: " +
454 0 : wall_boundaries[bc_ind]);
455 30 : const std::string bc_type = "INSFVTurbulentTemperatureWallFunction";
456 30 : InputParameters params = getFactory().getValidParams(bc_type);
457 60 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
458 90 : params.set<std::vector<BoundaryName>>("boundary") = {wall_boundaries[bc_ind]};
459 30 : params.set<MooseEnum>("wall_treatment") =
460 90 : _turbulence_physics->turbulenceTemperatureWallTreatment();
461 30 : params.set<MooseFunctorName>("T_w") = _energy_wall_functors[bc_ind];
462 30 : params.set<MooseFunctorName>(NS::density) = _density_name;
463 30 : params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
464 90 : params.set<MooseFunctorName>(NS::TKE) = _turbulence_physics->tkeName();
465 30 : if (_thermal_conductivity_name.size() != 1)
466 0 : mooseError("Several anisotropic thermal conductivity (kappa) regions have been specified. "
467 : "Selecting the right kappa coefficient for the turbulence boundaries is not "
468 0 : "currently implemented.\nBoundaries:\n" +
469 0 : Moose::stringify(_turbulence_physics->turbulenceWalls()) +
470 0 : "\nKappa(s) specified:\n" + Moose::stringify(_thermal_conductivity_name));
471 30 : params.set<MooseFunctorName>(NS::kappa) = _thermal_conductivity_name[0];
472 30 : params.set<MooseFunctorName>(NS::cp) = _specific_heat_name;
473 120 : const std::string u_names[3] = {"u", "v", "w"};
474 90 : for (const auto d : make_range(dimension()))
475 120 : params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
476 : // Currently only Newton method for WCNSFVFluidHeatTransferPhysics
477 30 : params.set<bool>("newton_solve") = true;
478 90 : getProblem().addFVBC(bc_type, prefix() + "wallfunction_" + wall_boundaries[bc_ind], params);
479 150 : }
480 : else
481 0 : paramError(
482 0 : "energy_wall_types", _energy_wall_types[bc_ind], " wall type is currently unsupported.");
483 : }
484 372 : }
485 :
486 : void
487 667 : WCNSFVFluidHeatTransferPhysics::addMaterials()
488 : {
489 667 : if (!_has_energy_equation)
490 281 : return;
491 :
492 : // Note that this material choice does not make sense for Newton-INSFV + solve_for_enthalpy since
493 : // this material explicitly computes enthalpy from temperature
494 : const auto object_type = "INSFVEnthalpyFunctorMaterial";
495 :
496 386 : InputParameters params = getFactory().getValidParams(object_type);
497 386 : assignBlocks(params, _blocks);
498 :
499 386 : params.set<MooseFunctorName>(NS::density) = _density_name;
500 386 : params.set<MooseFunctorName>(NS::cp) = _specific_heat_name;
501 :
502 : // In all cases, the functor material defines rho_h and dh/dt
503 : // 1st case, we solve for h, the functor material also defines T_fluid
504 386 : if (_solve_for_enthalpy)
505 : {
506 27 : params.set<MooseFunctorName>(NS::pressure) = _flow_equations_physics->getPressureName();
507 54 : params.set<MooseFunctorName>(NS::specific_enthalpy + "_in") = _fluid_enthalpy_name;
508 27 : params.set<bool>("assumed_constant_cp") = false;
509 27 : if (isParamValid(NS::fluid))
510 27 : params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
511 : else
512 0 : paramError(NS::fluid, "Required when solving for enthalpy");
513 : }
514 : // the functor material computes enthalpy from the temperature
515 : else
516 : {
517 718 : params.set<MooseFunctorName>("temperature") = _fluid_temperature_name;
518 718 : params.set<MooseFunctorName>(NS::specific_enthalpy) = _fluid_enthalpy_name;
519 :
520 : // using the fluid properties instead of assuming a constant cp
521 359 : if (isParamValid(NS::fluid))
522 : {
523 9 : params.set<bool>("assumed_constant_cp") = false;
524 9 : params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
525 18 : params.set<MooseFunctorName>(NS::pressure) = _flow_equations_physics->getPressureName();
526 : }
527 : }
528 : // We'll default to outputting the temperature because it's a common need
529 386 : if (_solve_for_enthalpy)
530 : {
531 81 : params.set<std::vector<std::string>>("output_properties") = {_fluid_temperature_name};
532 81 : params.set<std::vector<OutputName>>("outputs") = {"all"};
533 : }
534 :
535 1158 : getProblem().addMaterial(object_type, prefix() + "enthalpy_material", params);
536 :
537 386 : if (_solve_for_enthalpy)
538 27 : WCNSFVFluidHeatTransferPhysicsBase::defineEffectiveThermalDiffusionCoeffFunctors(
539 : /*use ad*/ true);
540 413 : }
541 :
542 : void
543 372 : WCNSFVFluidHeatTransferPhysics::addEnergySeparatorBC()
544 : {
545 372 : if (_flow_equations_physics->getHydraulicSeparators().size())
546 : {
547 : const auto & solver_variable_name =
548 9 : _solve_for_enthalpy ? _fluid_enthalpy_name : _fluid_temperature_name;
549 :
550 9 : const std::string bc_type = "INSFVScalarFieldSeparatorBC";
551 9 : InputParameters params = getFactory().getValidParams(bc_type);
552 18 : params.set<NonlinearVariableName>("variable") = solver_variable_name;
553 18 : params.set<std::vector<BoundaryName>>("boundary") =
554 18 : _flow_equations_physics->getHydraulicSeparators();
555 18 : getProblem().addFVBC(bc_type, prefix() + solver_variable_name + "_separators", params);
556 9 : }
557 372 : }
|