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 "WCNSLinearFVFlowPhysics.h"
11 : #include "WCNSFVTurbulencePhysics.h"
12 : #include "NSFVBase.h"
13 : #include "INSFVMomentumAdvection.h"
14 : #include "RhieChowMassFlux.h"
15 : #include "INSFVTimeKernel.h"
16 : #include "MapConversionUtils.h"
17 : #include "NS.h"
18 :
19 : registerWCNSFVFlowPhysicsBaseTasks("NavierStokesApp", WCNSLinearFVFlowPhysics);
20 : registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_linear_fv_kernel");
21 : registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_linear_fv_bc");
22 : registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_functor_material");
23 :
24 : InputParameters
25 199 : WCNSLinearFVFlowPhysics::validParams()
26 : {
27 199 : InputParameters params = WCNSFVFlowPhysicsBase::validParams();
28 199 : params.addClassDescription(
29 : "Define the Navier Stokes weakly-compressible equations with the linear "
30 : "solver implementation of the SIMPLE scheme");
31 :
32 398 : params.addParam<bool>(
33 398 : "orthogonality_correction", false, "Whether to use orthogonality correction");
34 199 : params.set<unsigned short>("ghost_layers") = 1;
35 :
36 : // This will be adapted based on the dimension
37 398 : params.set<std::vector<SolverSystemName>>("system_names") = {
38 1393 : "u_system", "v_system", "w_system", "pressure_system"};
39 :
40 : // Implemented in the executioner
41 199 : params.suppressParameter<MooseEnum>("pinned_pressure_type");
42 199 : params.suppressParameter<Point>("pinned_pressure_point");
43 199 : params.suppressParameter<PostprocessorName>("pinned_pressure_value");
44 :
45 : // Not supported
46 199 : params.suppressParameter<bool>("add_flow_equations");
47 199 : params.set<bool>("porous_medium_treatment") = false;
48 398 : params.suppressParameter<bool>("porous_medium_treatment");
49 398 : params.set<MooseFunctorName>("porosity") = "1";
50 199 : params.suppressParameter<MooseFunctorName>("porosity");
51 199 : params.suppressParameter<MooseEnum>("mu_interp_method");
52 : // Not needed
53 199 : params.suppressParameter<bool>("add_flow_equations");
54 199 : params.suppressParameter<MooseEnum>("preconditioning");
55 :
56 : // No other options so far
57 398 : params.set<MooseEnum>("velocity_interpolation") = "rc";
58 199 : params.suppressParameter<MooseEnum>("velocity_interpolation");
59 :
60 199 : return params;
61 0 : }
62 :
63 199 : WCNSLinearFVFlowPhysics::WCNSLinearFVFlowPhysics(const InputParameters & parameters)
64 : : WCNSFVFlowPhysicsBase(parameters),
65 398 : _non_orthogonal_correction(getParam<bool>("orthogonality_correction"))
66 : {
67 199 : if (_porous_medium_treatment)
68 0 : paramError("porous_medium_treatment", "Porous media unsupported");
69 199 : if (!_has_flow_equations)
70 0 : mooseError("Not supported");
71 :
72 199 : if (_hydraulic_separators.size())
73 0 : paramError("hydraulic_separator_sidesets",
74 : "Flow separators are not supported yet for linearFV!");
75 398 : if (getParam<bool>("pin_pressure"))
76 0 : paramError("pin_pressure",
77 : "Pressure pinning is implemented in the executioner for the linear finite volume "
78 : "segregated solves");
79 199 : }
80 :
81 : void
82 199 : WCNSLinearFVFlowPhysics::initializePhysicsAdditional()
83 : {
84 199 : WCNSFVFlowPhysicsBase::initializePhysicsAdditional();
85 : // TODO Add support for multi-system by either:
86 : // - creating the problem in the Physics or,
87 : // - checking that the right systems are being created
88 199 : getProblem().needSolutionState(2, Moose::SolutionIterationType::Nonlinear);
89 : // TODO Ban all other nonlinear Physics for now
90 :
91 : // Fix the default system names if using a different dimension
92 398 : if (!isParamSetByUser("system_name"))
93 : {
94 199 : if (dimension() == 1)
95 112 : _system_names = {"u_system", "pressure_system"};
96 171 : else if (dimension() == 2)
97 810 : _system_names = {"u_system", "v_system", "pressure_system"};
98 : }
99 199 : }
100 :
101 : void
102 199 : WCNSLinearFVFlowPhysics::addSolverVariables()
103 : {
104 199 : if (!_has_flow_equations)
105 0 : return;
106 :
107 578 : for (const auto d : make_range(dimension()))
108 758 : saveSolverVariableName(_velocity_names[d]);
109 199 : saveSolverVariableName(_pressure_name);
110 :
111 199 : const std::vector<std::string> v_short = {"u", "v", "w"};
112 :
113 : // Check number of variables
114 199 : if (_velocity_names.size() != dimension() && _velocity_names.size() != 3)
115 0 : paramError("velocity_variable",
116 0 : "The number of velocity variable names supplied to the NSFVAction is not " +
117 0 : Moose::stringify(dimension()) + " (mesh dimension)" +
118 0 : ((dimension() == 3) ? "" : " or 3!") + "\nVelocity variables " +
119 0 : Moose::stringify(_velocity_names));
120 :
121 : // Velocities
122 578 : for (const auto d : make_range(dimension()))
123 : {
124 758 : if (!shouldCreateVariable(_velocity_names[d], _blocks, /*error if aux*/ true))
125 0 : reportPotentiallyMissedParameters({"system_names"}, "MooseLinearVariableFVReal");
126 379 : else if (_define_variables)
127 : {
128 379 : std::string variable_type = "MooseLinearVariableFVReal";
129 :
130 379 : auto params = getFactory().getValidParams(variable_type);
131 379 : assignBlocks(params, _blocks);
132 758 : params.set<SolverSystemName>("solver_sys") = getSolverSystem(_velocity_names[d]);
133 :
134 379 : getProblem().addVariable(variable_type, _velocity_names[d], params);
135 379 : }
136 : else
137 0 : paramError("velocity_variable",
138 0 : "Variable (" + _velocity_names[d] +
139 : ") supplied to the WCNSLinearFVFlowPhysics does not exist!");
140 : }
141 :
142 : // Pressure
143 398 : if (!shouldCreateVariable(_pressure_name, _blocks, /*error if aux*/ true))
144 0 : reportPotentiallyMissedParameters({"system_names"}, "MooseLinearVariableFVReal");
145 199 : else if (_define_variables)
146 : {
147 : const auto pressure_type = "MooseLinearVariableFVReal";
148 :
149 199 : auto params = getFactory().getValidParams(pressure_type);
150 199 : assignBlocks(params, _blocks);
151 398 : params.set<SolverSystemName>("solver_sys") = getSolverSystem(_pressure_name);
152 :
153 199 : getProblem().addVariable(pressure_type, _pressure_name, params);
154 199 : }
155 : else
156 0 : paramError("pressure_variable",
157 0 : "Variable (" + _pressure_name +
158 : ") supplied to the WCNSLinearFVFlowPhysics does not exist!");
159 199 : }
160 :
161 : void
162 199 : WCNSLinearFVFlowPhysics::addFVKernels()
163 : {
164 199 : if (!_has_flow_equations)
165 : return;
166 :
167 : // Pressure correction equation: divergence of momentum
168 199 : addPressureCorrectionKernels();
169 :
170 : // Momentum equation: time derivative
171 199 : if (isTransient())
172 70 : addMomentumTimeKernels();
173 :
174 : // Momentum equation: flux terms
175 199 : addMomentumFluxKernels();
176 :
177 : // Momentum equation: pressure term
178 199 : addMomentumPressureKernels();
179 :
180 : // Momentum equation: friction term
181 199 : if (_friction_types.size())
182 38 : addMomentumFrictionKernels();
183 :
184 : // Momentum equation: gravity source term
185 199 : addMomentumGravityKernels();
186 :
187 : // Momentum equation: boussinesq approximation
188 398 : if (getParam<bool>("boussinesq_approximation"))
189 19 : addMomentumBoussinesqKernels();
190 : }
191 :
192 : void
193 199 : WCNSLinearFVFlowPhysics::addPressureCorrectionKernels()
194 : {
195 : {
196 199 : std::string kernel_type = "LinearFVAnisotropicDiffusion";
197 398 : std::string kernel_name = prefix() + "p_diffusion";
198 :
199 199 : InputParameters params = getFactory().getValidParams(kernel_type);
200 199 : assignBlocks(params, _blocks);
201 398 : params.set<LinearVariableName>("variable") = _pressure_name;
202 398 : params.set<MooseFunctorName>("diffusion_tensor") = "Ainv";
203 199 : params.set<bool>("use_nonorthogonal_correction") = _non_orthogonal_correction;
204 :
205 199 : getProblem().addLinearFVKernel(kernel_type, kernel_name, params);
206 199 : }
207 : {
208 199 : std::string kernel_type = "LinearFVDivergence";
209 398 : std::string kernel_name = prefix() + "HbyA_divergence";
210 :
211 199 : InputParameters params = getFactory().getValidParams(kernel_type);
212 199 : assignBlocks(params, _blocks);
213 398 : params.set<LinearVariableName>("variable") = _pressure_name;
214 398 : params.set<MooseFunctorName>("face_flux") = "HbyA";
215 199 : params.set<bool>("force_boundary_execution") = true;
216 :
217 199 : getProblem().addLinearFVKernel(kernel_type, kernel_name, params);
218 199 : }
219 199 : }
220 :
221 : void
222 70 : WCNSLinearFVFlowPhysics::addMomentumTimeKernels()
223 : {
224 70 : std::string kernel_type = "LinearFVTimeDerivative";
225 140 : std::string kernel_name = prefix() + "ins_momentum_time";
226 :
227 70 : InputParameters params = getFactory().getValidParams(kernel_type);
228 70 : assignBlocks(params, _blocks);
229 70 : params.set<MooseFunctorName>("factor") = _density_name;
230 :
231 261 : for (const auto d : make_range(dimension()))
232 : {
233 242 : params.set<LinearVariableName>("variable") = _velocity_names[d];
234 242 : if (shouldCreateTimeDerivative(_velocity_names[d], _blocks, /*error if already defined*/ false))
235 242 : getProblem().addLinearFVKernel(kernel_type, kernel_name + "_" + NS::directions[d], params);
236 : }
237 140 : }
238 :
239 : void
240 199 : WCNSLinearFVFlowPhysics::addMomentumFluxKernels()
241 : {
242 796 : const std::string u_names[3] = {"u", "v", "w"};
243 199 : std::string kernel_type = "LinearWCNSFVMomentumFlux";
244 398 : std::string kernel_name = prefix() + "ins_momentum_flux_";
245 :
246 199 : InputParameters params = getFactory().getValidParams(kernel_type);
247 199 : assignBlocks(params, _blocks);
248 199 : params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
249 398 : params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
250 199 : params.set<MooseEnum>("advected_interp_method") = _momentum_advection_interpolation;
251 199 : params.set<bool>("use_nonorthogonal_correction") = _non_orthogonal_correction;
252 398 : params.set<bool>("use_deviatoric_terms") = getParam<bool>("include_deviatoric_stress");
253 :
254 578 : for (unsigned int i = 0; i < dimension(); ++i)
255 758 : params.set<SolverVariableName>(u_names[i]) = _velocity_names[i];
256 :
257 777 : for (const auto d : make_range(dimension()))
258 : {
259 758 : params.set<LinearVariableName>("variable") = _velocity_names[d];
260 758 : params.set<MooseEnum>("momentum_component") = NS::directions[d];
261 :
262 758 : getProblem().addLinearFVKernel(kernel_type, kernel_name + NS::directions[d], params);
263 : }
264 1194 : }
265 :
266 : void
267 199 : WCNSLinearFVFlowPhysics::addMomentumPressureKernels()
268 : {
269 199 : std::string kernel_type = "LinearFVMomentumPressure";
270 398 : std::string kernel_name = prefix() + "ins_momentum_pressure_";
271 :
272 199 : InputParameters params = getFactory().getValidParams(kernel_type);
273 199 : assignBlocks(params, _blocks);
274 398 : params.set<VariableName>("pressure") = _pressure_name;
275 :
276 777 : for (const auto d : make_range(dimension()))
277 : {
278 379 : params.set<MooseEnum>("momentum_component") = NS::directions[d];
279 758 : params.set<LinearVariableName>("variable") = _velocity_names[d];
280 758 : getProblem().addLinearFVKernel(kernel_type, kernel_name + NS::directions[d], params);
281 : }
282 398 : }
283 :
284 : void
285 38 : WCNSLinearFVFlowPhysics::addMomentumFrictionKernels()
286 : {
287 38 : unsigned int num_friction_blocks = _friction_blocks.size();
288 : unsigned int num_used_blocks = num_friction_blocks ? num_friction_blocks : 1;
289 :
290 38 : const std::string kernel_type = "LinearFVMomentumFriction";
291 38 : InputParameters params = getFactory().getValidParams(kernel_type);
292 :
293 76 : for (const auto block_i : make_range(num_used_blocks))
294 : {
295 38 : std::string block_name = "";
296 38 : if (num_friction_blocks)
297 : {
298 0 : params.set<std::vector<SubdomainName>>("block") = _friction_blocks[block_i];
299 0 : block_name = Moose::stringify(_friction_blocks[block_i]);
300 : }
301 : else
302 : {
303 38 : assignBlocks(params, _blocks);
304 76 : block_name = std::to_string(block_i);
305 : }
306 :
307 114 : for (const auto d : make_range(dimension()))
308 : {
309 152 : params.set<LinearVariableName>("variable") = _velocity_names[d];
310 76 : params.set<MooseEnum>("momentum_component") = NS::directions[d];
311 152 : for (unsigned int type_i = 0; type_i < _friction_types[block_i].size(); ++type_i)
312 : {
313 76 : const auto upper_name = MooseUtils::toUpper(_friction_types[block_i][type_i]);
314 76 : if (upper_name == "DARCY")
315 : {
316 76 : params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
317 152 : params.set<MooseFunctorName>("Darcy_name") = _friction_coeffs[block_i][type_i];
318 : }
319 : else
320 0 : paramError("momentum_friction_types",
321 : "Friction type '",
322 : _friction_types[block_i][type_i],
323 : "' is not implemented");
324 : }
325 :
326 76 : getProblem().addLinearFVKernel(kernel_type,
327 304 : prefix() + "momentum_friction_" + block_name + "_" +
328 : NS::directions[d],
329 : params);
330 : }
331 : }
332 76 : }
333 :
334 : void
335 199 : WCNSLinearFVFlowPhysics::addMomentumGravityKernels()
336 : {
337 398 : if (parameters().isParamValid("gravity") && !_solve_for_dynamic_pressure)
338 : {
339 180 : std::string kernel_type = "LinearFVSource";
340 360 : std::string kernel_name = prefix() + "ins_momentum_gravity_";
341 :
342 180 : InputParameters params = getFactory().getValidParams(kernel_type);
343 180 : assignBlocks(params, _blocks);
344 360 : const auto gravity_vector = getParam<RealVectorValue>("gravity");
345 900 : const std::vector<std::string> comp_axis({"x", "y", "z"});
346 :
347 521 : for (const auto d : make_range(dimension()))
348 341 : if (gravity_vector(d) != 0)
349 : {
350 8 : params.set<MooseFunctorName>("source_density") = "rho_g_" + comp_axis[d];
351 4 : params.set<LinearVariableName>("variable") = _velocity_names[d];
352 :
353 4 : getProblem().addLinearFVKernel(kernel_type, kernel_name + NS::directions[d], params);
354 : }
355 180 : }
356 559 : }
357 :
358 : void
359 19 : WCNSLinearFVFlowPhysics::addMomentumBoussinesqKernels()
360 : {
361 19 : if (_compressibility == "weakly-compressible")
362 0 : paramError("boussinesq_approximation",
363 : "We cannot use boussinesq approximation while running in weakly-compressible mode!");
364 :
365 19 : std::string kernel_type = "LinearFVMomentumBoussinesq";
366 38 : std::string kernel_name = prefix() + "ins_momentum_boussinesq_";
367 :
368 19 : InputParameters params = getFactory().getValidParams(kernel_type);
369 19 : assignBlocks(params, _blocks);
370 19 : params.set<VariableName>(NS::T_fluid) = _fluid_temperature_name;
371 19 : params.set<MooseFunctorName>(NS::density) = _density_gravity_name;
372 38 : params.set<RealVectorValue>("gravity") = getParam<RealVectorValue>("gravity");
373 38 : params.set<Real>("ref_temperature") = getParam<Real>("ref_temperature");
374 57 : params.set<MooseFunctorName>("alpha_name") = getParam<MooseFunctorName>("thermal_expansion");
375 :
376 76 : for (const auto d : make_range(dimension()))
377 : {
378 38 : params.set<MooseEnum>("momentum_component") = NS::directions[d];
379 76 : params.set<LinearVariableName>("variable") = _velocity_names[d];
380 :
381 76 : getProblem().addLinearFVKernel(kernel_type, kernel_name + NS::directions[d], params);
382 : }
383 38 : }
384 :
385 : void
386 199 : WCNSLinearFVFlowPhysics::addInletBC()
387 : {
388 : // Check the size of the BC parameters
389 : unsigned int num_velocity_functor_inlets = 0;
390 377 : for (const auto & [bdy, momentum_inlet_type] : _momentum_inlet_types)
391 178 : if (momentum_inlet_type == "fixed-velocity" || momentum_inlet_type == "fixed-pressure")
392 178 : num_velocity_functor_inlets++;
393 :
394 199 : if (num_velocity_functor_inlets != _momentum_inlet_functors.size())
395 0 : paramError("momentum_inlet_functors",
396 0 : "Size (" + std::to_string(_momentum_inlet_functors.size()) +
397 : ") is not the same as the number of entries in the momentum_inlet_types "
398 0 : "subvector for fixed-velocities/pressures functors (size " +
399 0 : std::to_string(num_velocity_functor_inlets) + ")");
400 :
401 : unsigned int velocity_pressure_counter = 0;
402 377 : for (const auto & [inlet_bdy, momentum_inlet_type] : _momentum_inlet_types)
403 : {
404 178 : if (momentum_inlet_type == "fixed-velocity")
405 : {
406 178 : const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
407 178 : InputParameters params = getFactory().getValidParams(bc_type);
408 534 : params.set<std::vector<BoundaryName>>("boundary") = {inlet_bdy};
409 178 : if (_momentum_inlet_functors.size() < velocity_pressure_counter + 1)
410 0 : paramError("momentum_inlet_functors",
411 0 : "More non-flux inlets than inlet functors (" +
412 0 : std::to_string(_momentum_inlet_functors.size()) + ")");
413 :
414 : // Check that enough functors have been provided for the dimension of the problem
415 178 : const auto momentum_functors = libmesh_map_find(_momentum_inlet_functors, inlet_bdy);
416 178 : if (momentum_functors.size() < dimension())
417 0 : paramError("momentum_inlet_functors",
418 0 : "Subvector for boundary '" + inlet_bdy + "' (size " +
419 0 : std::to_string(momentum_functors.size()) +
420 0 : ") is not the same size as the number of dimensions of the physics (" +
421 0 : std::to_string(dimension()) + ")");
422 :
423 515 : for (const auto d : make_range(dimension()))
424 : {
425 674 : params.set<LinearVariableName>("variable") = _velocity_names[d];
426 674 : params.set<MooseFunctorName>("functor") = momentum_functors[d];
427 :
428 674 : getProblem().addLinearFVBC(bc_type, _velocity_names[d] + "_" + inlet_bdy, params);
429 : }
430 : ++velocity_pressure_counter;
431 :
432 : // Add the two term BC expansion for pressure if requested
433 356 : if (getParam<bool>("pressure_two_term_bc_expansion"))
434 : {
435 58 : const std::string bc_type = "LinearFVExtrapolatedPressureBC";
436 58 : InputParameters params = getFactory().getValidParams(bc_type);
437 174 : params.set<std::vector<BoundaryName>>("boundary") = {inlet_bdy};
438 116 : params.set<LinearVariableName>("variable") = _pressure_name;
439 58 : params.set<bool>("use_two_term_expansion") = true;
440 58 : getProblem().addLinearFVBC(bc_type,
441 116 : _pressure_name + "_extrapolation_inlet_" +
442 58 : Moose::stringify(inlet_bdy),
443 : params);
444 58 : }
445 178 : }
446 0 : else if (momentum_inlet_type == "fixed-pressure")
447 : {
448 0 : const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
449 0 : InputParameters params = getFactory().getValidParams(bc_type);
450 0 : params.set<LinearVariableName>("variable") = _pressure_name;
451 0 : if (_momentum_inlet_functors.size() < velocity_pressure_counter + 1)
452 0 : paramError("momentum_inlet_functors",
453 0 : "More non-flux inlets than inlet functors (" +
454 0 : std::to_string(_momentum_inlet_functors.size()) + ")");
455 :
456 0 : params.set<MooseFunctorName>("functor") =
457 0 : libmesh_map_find(_momentum_inlet_functors, inlet_bdy)[0];
458 0 : params.set<std::vector<BoundaryName>>("boundary") = {inlet_bdy};
459 :
460 0 : getProblem().addLinearFVBC(bc_type, _pressure_name + "_" + inlet_bdy, params);
461 : ++velocity_pressure_counter;
462 0 : }
463 : else
464 0 : mooseError("Unsupported inlet boundary condition type: ", momentum_inlet_type);
465 : }
466 199 : }
467 :
468 : void
469 199 : WCNSLinearFVFlowPhysics::addOutletBC()
470 : {
471 : // Check the BCs size
472 : unsigned int num_pressure_outlets = 0;
473 368 : for (const auto & [bdy, momentum_outlet_type] : _momentum_outlet_types)
474 178 : if (momentum_outlet_type == "fixed-pressure" ||
475 9 : momentum_outlet_type == "fixed-pressure-zero-gradient")
476 169 : num_pressure_outlets++;
477 :
478 199 : if (num_pressure_outlets != _pressure_functors.size())
479 0 : paramError("pressure_functors",
480 0 : "Size (" + std::to_string(_pressure_functors.size()) +
481 : ") is not the same as the number of pressure outlet boundaries in "
482 0 : "'fixed-pressure/fixed-pressure-zero-gradient' (size " +
483 0 : std::to_string(num_pressure_outlets) + ")");
484 :
485 796 : const std::string u_names[3] = {"u", "v", "w"};
486 368 : for (const auto & [outlet_bdy, momentum_outlet_type] : _momentum_outlet_types)
487 : {
488 : // Zero tangeantial gradient condition on velocity
489 178 : if (momentum_outlet_type == "zero-gradient" || momentum_outlet_type == "fixed-pressure" ||
490 9 : momentum_outlet_type == "fixed-pressure-zero-gradient")
491 : {
492 169 : const std::string bc_type = "LinearFVAdvectionDiffusionOutflowBC";
493 169 : InputParameters params = getFactory().getValidParams(bc_type);
494 507 : params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
495 338 : params.set<bool>("use_two_term_expansion") = getParam<bool>("momentum_two_term_bc_expansion");
496 :
497 488 : for (const auto d : make_range(dimension()))
498 : {
499 638 : params.set<LinearVariableName>("variable") = _velocity_names[d];
500 638 : getProblem().addLinearFVBC(bc_type, _velocity_names[d] + "_" + outlet_bdy, params);
501 : }
502 169 : }
503 :
504 : // Fixed pressure condition, coming in the pressure correction equation
505 178 : if (momentum_outlet_type == "fixed-pressure" ||
506 9 : momentum_outlet_type == "fixed-pressure-zero-gradient")
507 : {
508 169 : const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
509 169 : InputParameters params = getFactory().getValidParams(bc_type);
510 338 : params.set<LinearVariableName>("variable") = _pressure_name;
511 338 : params.set<MooseFunctorName>("functor") = libmesh_map_find(_pressure_functors, outlet_bdy);
512 507 : params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
513 :
514 169 : getProblem().addLinearFVBC(bc_type, _pressure_name + "_" + outlet_bdy, params);
515 169 : }
516 : }
517 995 : }
518 :
519 : void
520 199 : WCNSLinearFVFlowPhysics::addWallsBC()
521 : {
522 796 : const std::string u_names[3] = {"u", "v", "w"};
523 :
524 630 : for (const auto & [boundary_name, momentum_wall_type] : _momentum_wall_types)
525 : {
526 431 : if (momentum_wall_type == "noslip")
527 : {
528 431 : const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
529 431 : InputParameters params = getFactory().getValidParams(bc_type);
530 1293 : params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
531 :
532 1329 : for (const auto d : make_range(dimension()))
533 : {
534 1796 : params.set<LinearVariableName>("variable") = _velocity_names[d];
535 : if (_momentum_wall_functors.count(boundary_name) == 0)
536 1388 : params.set<MooseFunctorName>("functor") = "0";
537 : else
538 408 : params.set<MooseFunctorName>("functor") = _momentum_wall_functors[boundary_name][d];
539 :
540 1796 : getProblem().addLinearFVBC(bc_type, _velocity_names[d] + "_" + boundary_name, params);
541 : }
542 431 : }
543 : else
544 0 : mooseError("Unsupported wall boundary condition type: " + std::string(momentum_wall_type));
545 : }
546 :
547 398 : if (getParam<bool>("pressure_two_term_bc_expansion"))
548 : {
549 79 : const std::string bc_type = "LinearFVExtrapolatedPressureBC";
550 79 : InputParameters params = getFactory().getValidParams(bc_type);
551 79 : params.set<std::vector<BoundaryName>>("boundary") = _wall_boundaries;
552 158 : params.set<LinearVariableName>("variable") = _pressure_name;
553 79 : params.set<bool>("use_two_term_expansion") = true;
554 79 : getProblem().addLinearFVBC(
555 237 : bc_type, _pressure_name + "_extrapolation_" + Moose::stringify(_wall_boundaries), params);
556 79 : }
557 995 : }
558 :
559 : void
560 199 : WCNSLinearFVFlowPhysics::addUserObjects()
561 : {
562 : // Rhie Chow user object for interpolation velocities
563 199 : addRhieChowUserObjects();
564 199 : }
565 :
566 : void
567 199 : WCNSLinearFVFlowPhysics::addRhieChowUserObjects()
568 : {
569 : mooseAssert(dimension(), "0-dimension not supported");
570 :
571 : // First make sure that we only add this object once
572 : // Potential cases:
573 : // - there is a flow physics, and an advection one (UO should be added by one)
574 : // - there is only an advection physics (UO should be created)
575 : // - there are two advection physics on different blocks with set velocities (first one picks)
576 : // Counting RC UOs defined on the same blocks seems to be the most fool proof option
577 : std::vector<UserObject *> objs;
578 : getProblem()
579 : .theWarehouse()
580 199 : .query()
581 199 : .condition<AttribSystem>("UserObject")
582 398 : .condition<AttribThread>(0)
583 : .queryInto(objs);
584 : unsigned int num_rc_uo = 0;
585 218 : for (const auto & obj : objs)
586 19 : if (dynamic_cast<RhieChowMassFlux *>(obj))
587 : {
588 : const auto rc_obj = dynamic_cast<RhieChowMassFlux *>(obj);
589 0 : if (rc_obj->blocks() == _blocks)
590 0 : num_rc_uo++;
591 : // one of the RC user object is defined everywhere
592 0 : else if (rc_obj->blocks().size() == 0 || _blocks.size() == 0)
593 0 : num_rc_uo++;
594 : }
595 :
596 199 : if (num_rc_uo)
597 : return;
598 :
599 796 : const std::string u_names[3] = {"u", "v", "w"};
600 : const auto object_type = "RhieChowMassFlux";
601 :
602 199 : auto params = getFactory().getValidParams(object_type);
603 199 : assignBlocks(params, _blocks);
604 578 : for (unsigned int d = 0; d < dimension(); ++d)
605 758 : params.set<VariableName>(u_names[d]) = _velocity_names[d];
606 :
607 398 : params.set<VariableName>("pressure") = _pressure_name;
608 597 : params.set<std::string>("p_diffusion_kernel") = prefix() + "p_diffusion";
609 199 : params.set<MooseFunctorName>(NS::density) = _density_name;
610 :
611 398 : getProblem().addUserObject(object_type, rhieChowUOName(), params);
612 995 : }
613 :
614 : void
615 199 : WCNSLinearFVFlowPhysics::addFunctorMaterials()
616 : {
617 398 : if (parameters().isParamValid("gravity"))
618 : {
619 398 : const auto gravity_vector = getParam<RealVectorValue>("gravity");
620 995 : const std::vector<std::string> comp_axis({"x", "y", "z"});
621 578 : for (const auto d : make_range(dimension()))
622 379 : if (gravity_vector(d) != 0)
623 : {
624 : // Add rho * g functor for each relevant direction
625 : // TODO: we could avoid using an AD functor material for non-AD density functor
626 21 : auto params = getFactory().getValidParams("ADParsedFunctorMaterial");
627 21 : assignBlocks(params, _blocks);
628 42 : params.set<std::string>("expression") =
629 63 : _density_gravity_name + " * " + std::to_string(gravity_vector(d));
630 21 : if (!MooseUtils::parsesToReal(_density_gravity_name))
631 6 : params.set<std::vector<std::string>>("functor_names") = {_density_gravity_name};
632 42 : params.set<std::string>("property_name") = "rho_g_" + comp_axis[d];
633 : // We don't output this helper material
634 63 : getProblem().addMaterial(
635 42 : "ADParsedFunctorMaterial", prefix() + "gravity_helper_" + comp_axis[d], params);
636 21 : }
637 199 : }
638 599 : }
639 :
640 : UserObjectName
641 578 : WCNSLinearFVFlowPhysics::rhieChowUOName() const
642 : {
643 : mooseAssert(!_porous_medium_treatment, "Not implemented");
644 578 : return "ins_rhie_chow_interpolator";
645 : }
646 :
647 : unsigned short
648 1023 : WCNSLinearFVFlowPhysics::getNumberAlgebraicGhostingLayersNeeded() const
649 : {
650 1023 : return 1;
651 : }
|