https://mooseframework.inl.gov
Loading...
Searching...
No Matches
WCNSLinearFVFlowPhysics.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
12#include "NSFVBase.h"
14#include "RhieChowMassFlux.h"
15#include "INSFVTimeKernel.h"
16#include "MapConversionUtils.h"
17#include "NSFVUtils.h"
18#include "NS.h"
19
21registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_interpolation_method_physics");
22registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_linear_fv_kernel");
23registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_linear_fv_bc");
24registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_functor_material");
25
28{
31 "Define the Navier Stokes weakly-compressible equations with the linear "
32 "solver implementation of the SIMPLE scheme");
33 params.set<MooseEnum>("momentum_advection_interpolation") = NS::fvAdvectedInterpolationMethods();
34 params.addParam<InterpolationMethodName>(
35 "momentum_advection_interpolation_method_name",
36 "Name of an externally defined FVInterpolationMethod to use for momentum advection. When "
37 "provided, this overrides 'momentum_advection_interpolation'.");
38
39 params.addParam<bool>(
40 "orthogonality_correction", false, "Whether to use orthogonality correction");
41 params.renameParam("orthogonality_correction", "use_nonorthogonal_correction", "");
42 params.addParam<MooseEnum>(
43 "pressure_diffusion_interpolation",
45 "The face interpolation method for Ainv in the pressure correction diffusion term.");
46 params.addParamNamesToGroup("pressure_diffusion_interpolation", "Numerical scheme");
47 params.set<unsigned short>("ghost_layers") = 1;
48
49 // This will be adapted based on the dimension
50 params.set<std::vector<SolverSystemName>>("system_names") = {
51 "u_system", "v_system", "w_system", "pressure_system"};
52
53 // Implemented in the executioner
54 params.suppressParameter<MooseEnum>("pinned_pressure_type");
55 params.suppressParameter<Point>("pinned_pressure_point");
56 params.suppressParameter<PostprocessorName>("pinned_pressure_value");
57
58 // Not supported
59 params.suppressParameter<bool>("add_flow_equations");
60 params.set<bool>("porous_medium_treatment") = false;
61 params.suppressParameter<bool>("porous_medium_treatment");
62 params.set<MooseFunctorName>("porosity") = "1";
63 params.suppressParameter<MooseFunctorName>("porosity");
64 params.suppressParameter<MooseEnum>("mu_interp_method");
65 // Not needed
66 params.suppressParameter<bool>("add_flow_equations");
67 params.suppressParameter<MooseEnum>("preconditioning");
68
69 // No other options so far
70 params.set<MooseEnum>("velocity_interpolation") = "rc";
71 params.suppressParameter<MooseEnum>("velocity_interpolation");
72
73 // Rhie-Chow
74 params.transferParam<MooseEnum>(RhieChowMassFlux::validParams(), "pressure_projection_method");
75 params.addParamNamesToGroup("momentum_advection_interpolation_method_name", "Numerical scheme");
76
77 return params;
78}
79
81 : WCNSFVFlowPhysicsBase(parameters),
82 _non_orthogonal_correction(getParam<bool>("orthogonality_correction"))
83{
84 addRequiredPhysicsTask("add_interpolation_method_physics");
85
87 paramError("porous_medium_treatment", "Porous media unsupported");
89 mooseError("Not supported");
90
91 if (_hydraulic_separators.size())
92 paramError("hydraulic_separator_sidesets",
93 "Flow separators are not supported yet for linearFV!");
94 if (getParam<bool>("pin_pressure"))
95 paramError("pin_pressure",
96 "Pressure pinning is implemented in the executioner for the linear finite volume "
97 "segregated solves");
98}
99
100void
102{
103 if (!_has_flow_equations || isParamValid("momentum_advection_interpolation_method_name"))
104 return;
105
106 addFVAdvectedInterpolationMethod(getParam<MooseEnum>("momentum_advection_interpolation"));
107}
108
109void
111{
113 // TODO Add support for multi-system by either:
114 // - creating the problem in the Physics or,
115 // - checking that the right systems are being created
116 getProblem().needSolutionState(2, Moose::SolutionIterationType::Nonlinear);
117 // TODO Ban all other nonlinear Physics for now
118
119 // Fix the default system names if using a different dimension
120 if (!isParamSetByUser("system_name"))
121 {
122 if (dimension() == 1)
123 _system_names = {"u_system", "pressure_system"};
124 else if (dimension() == 2)
125 _system_names = {"u_system", "v_system", "pressure_system"};
126 }
127}
128
129void
131{
133 return;
134
135 for (const auto d : make_range(dimension()))
138
139 const std::vector<std::string> v_short = {"u", "v", "w"};
140
141 // Check number of variables
142 if (_velocity_names.size() != dimension() && _velocity_names.size() != 3)
143 paramError("velocity_variable",
144 "The number of velocity variable names supplied to the NSFVAction is not " +
145 Moose::stringify(dimension()) + " (mesh dimension)" +
146 ((dimension() == 3) ? "" : " or 3!") + "\nVelocity variables " +
148
149 // Velocities
150 for (const auto d : make_range(dimension()))
151 {
152 if (!shouldCreateVariable(_velocity_names[d], _blocks, /*error if aux*/ true))
153 reportPotentiallyMissedParameters({"system_names"}, "MooseLinearVariableFVReal");
154 else if (_define_variables)
155 {
156 std::string variable_type = "MooseLinearVariableFVReal";
157
158 auto params = getFactory().getValidParams(variable_type);
159 assignBlocks(params, _blocks);
160 params.set<SolverSystemName>("solver_sys") = getSolverSystem(_velocity_names[d]);
161
162 getProblem().addVariable(variable_type, _velocity_names[d], params);
163 }
164 else
165 paramError("velocity_variable",
166 "Variable (" + _velocity_names[d] +
167 ") supplied to the WCNSLinearFVFlowPhysics does not exist!");
168 }
169
170 // Pressure
171 if (!shouldCreateVariable(_pressure_name, _blocks, /*error if aux*/ true))
172 reportPotentiallyMissedParameters({"system_names"}, "MooseLinearVariableFVReal");
173 else if (_define_variables)
174 {
175 const auto pressure_type = "MooseLinearVariableFVReal";
176
177 auto params = getFactory().getValidParams(pressure_type);
178 assignBlocks(params, _blocks);
179 params.set<SolverSystemName>("solver_sys") = getSolverSystem(_pressure_name);
180
181 getProblem().addVariable(pressure_type, _pressure_name, params);
182 }
183 else
184 paramError("pressure_variable",
185 "Variable (" + _pressure_name +
186 ") supplied to the WCNSLinearFVFlowPhysics does not exist!");
187}
188
189void
191{
193 return;
194
195 // Pressure correction equation: divergence of momentum
197
198 // Momentum equation: time derivative
199 if (isTransient())
201
202 // Momentum equation: flux terms
204
205 // Momentum equation: pressure term
207
208 // Momentum equation: friction term
209 if (_friction_types.size())
211
212 // Momentum equation: gravity source term
214
215 // Momentum equation: boussinesq approximation
216 if (getParam<bool>("boussinesq_approximation"))
218}
219
220void
222{
223 {
224 std::string kernel_type = "LinearFVPressureCorrectionDiffusion";
225 std::string kernel_name = prefix() + "p_diffusion";
226
227 InputParameters params = getFactory().getValidParams(kernel_type);
228 assignBlocks(params, _blocks);
229 params.set<LinearVariableName>("variable") = _pressure_name;
230 params.set<MooseFunctorName>("diffusion_tensor") = "Ainv";
231 params.set<bool>("use_nonorthogonal_correction") = _non_orthogonal_correction;
232
233 getProblem().addLinearFVKernel(kernel_type, kernel_name, params);
234 }
235 {
236 std::string kernel_type = "LinearFVDivergence";
237 std::string kernel_name = prefix() + "HbyA_divergence";
238
239 InputParameters params = getFactory().getValidParams(kernel_type);
240 assignBlocks(params, _blocks);
241 params.set<LinearVariableName>("variable") = _pressure_name;
242 params.set<MooseFunctorName>("face_flux") = "HbyA";
243 params.set<bool>("force_boundary_execution") = true;
244
245 getProblem().addLinearFVKernel(kernel_type, kernel_name, params);
246 }
247}
248
249void
251{
252 std::string kernel_type = "LinearFVTimeDerivative";
253 std::string kernel_name = prefix() + "ins_momentum_time";
254
255 InputParameters params = getFactory().getValidParams(kernel_type);
256 assignBlocks(params, _blocks);
257 params.set<MooseFunctorName>("factor") = _density_name;
258
259 for (const auto d : make_range(dimension()))
260 {
261 params.set<LinearVariableName>("variable") = _velocity_names[d];
262 if (shouldCreateTimeDerivative(_velocity_names[d], _blocks, /*error if already defined*/ false))
263 getProblem().addLinearFVKernel(kernel_type, kernel_name + "_" + NS::directions[d], params);
264 }
265}
266
267void
269{
270 const auto momentum_advection_method_name =
271 isParamValid("momentum_advection_interpolation_method_name")
272 ? getParam<InterpolationMethodName>("momentum_advection_interpolation_method_name")
273 : InterpolationMethodName(
274 std::string(getParam<MooseEnum>("momentum_advection_interpolation")));
275
276 const std::string u_names[3] = {"u", "v", "w"};
277 std::string kernel_type = "LinearWCNSFVMomentumFlux";
278 std::string kernel_name = prefix() + "ins_momentum_flux_";
279
280 InputParameters params = getFactory().getValidParams(kernel_type);
281 assignBlocks(params, _blocks);
283 params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
284 else
285 params.set<MooseFunctorName>(NS::mu) = NS::mu_eff;
286
287 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
288 params.set<InterpolationMethodName>("advected_interp_method_name") =
289 momentum_advection_method_name;
290 params.set<bool>("use_nonorthogonal_correction") = _non_orthogonal_correction;
291 params.set<bool>("use_deviatoric_terms") = includeSymmetrizedViscousStress();
292
293 for (unsigned int i = 0; i < dimension(); ++i)
294 params.set<SolverVariableName>(u_names[i]) = _velocity_names[i];
295
296 for (const auto d : make_range(dimension()))
297 {
298 params.set<LinearVariableName>("variable") = _velocity_names[d];
299 params.set<MooseEnum>("momentum_component") = NS::directions[d];
300
301 getProblem().addLinearFVKernel(kernel_type, kernel_name + NS::directions[d], params);
302 }
303}
304
305void
307{
308 std::string kernel_type = "LinearFVMomentumPressure";
309 std::string kernel_name = prefix() + "ins_momentum_pressure_";
310
311 InputParameters params = getFactory().getValidParams(kernel_type);
312 assignBlocks(params, _blocks);
313 params.set<VariableName>("pressure") = _pressure_name;
314
315 for (const auto d : make_range(dimension()))
316 {
317 params.set<MooseEnum>("momentum_component") = NS::directions[d];
318 params.set<LinearVariableName>("variable") = _velocity_names[d];
319 getProblem().addLinearFVKernel(kernel_type, kernel_name + NS::directions[d], params);
320 }
321}
322
323void
325{
326 unsigned int num_friction_blocks = _friction_blocks.size();
327 unsigned int num_used_blocks = num_friction_blocks ? num_friction_blocks : 1;
328
329 const std::string kernel_type = "LinearFVMomentumFriction";
330 InputParameters params = getFactory().getValidParams(kernel_type);
331
332 for (const auto block_i : make_range(num_used_blocks))
333 {
334 std::string block_name = "";
335 if (num_friction_blocks)
336 {
337 params.set<std::vector<SubdomainName>>("block") = _friction_blocks[block_i];
338 block_name = Moose::stringify(_friction_blocks[block_i]);
339 }
340 else
341 {
342 assignBlocks(params, _blocks);
343 block_name = std::to_string(block_i);
344 }
345
346 for (const auto d : make_range(dimension()))
347 {
348 params.set<LinearVariableName>("variable") = _velocity_names[d];
349 params.set<MooseEnum>("momentum_component") = NS::directions[d];
350 for (unsigned int type_i = 0; type_i < _friction_types[block_i].size(); ++type_i)
351 {
352 const auto upper_name = MooseUtils::toUpper(_friction_types[block_i][type_i]);
353 if (upper_name == "DARCY")
354 {
355 params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
356 params.set<MooseFunctorName>("Darcy_name") = _friction_coeffs[block_i][type_i];
357 }
358 else
359 paramError("friction_types",
360 "Friction type '",
361 _friction_types[block_i][type_i],
362 "' is not implemented");
363 }
364
365 getProblem().addLinearFVKernel(kernel_type,
366 prefix() + "momentum_friction_" + block_name + "_" +
368 params);
369 }
370 }
371}
372
373void
375{
377 {
378 std::string kernel_type = "LinearFVSource";
379 std::string kernel_name = prefix() + "ins_momentum_gravity_";
380
381 InputParameters params = getFactory().getValidParams(kernel_type);
382 assignBlocks(params, _blocks);
383 const auto gravity_vector = getParam<RealVectorValue>("gravity");
384 const std::vector<std::string> comp_axis({"x", "y", "z"});
385
386 for (const auto d : make_range(dimension()))
387 if (gravity_vector(d) != 0)
388 {
389 params.set<MooseFunctorName>("source_density") = "rho_g_" + comp_axis[d];
390 params.set<LinearVariableName>("variable") = _velocity_names[d];
391
392 getProblem().addLinearFVKernel(kernel_type, kernel_name + NS::directions[d], params);
393 }
394 }
395}
396
397void
399{
400 if (_compressibility == "weakly-compressible")
401 paramError("boussinesq_approximation",
402 "We cannot use boussinesq approximation while running in weakly-compressible mode!");
403
404 std::string kernel_type = "LinearFVMomentumBoussinesq";
405 std::string kernel_name = prefix() + "ins_momentum_boussinesq_";
406
407 InputParameters params = getFactory().getValidParams(kernel_type);
408 assignBlocks(params, _blocks);
409 params.set<VariableName>(NS::T_fluid) = _fluid_temperature_name;
410 params.set<MooseFunctorName>(NS::density) = _density_gravity_name;
411 params.set<RealVectorValue>("gravity") = getParam<RealVectorValue>("gravity");
412 params.set<Real>("ref_temperature") = getParam<Real>("ref_temperature");
413 params.set<MooseFunctorName>("alpha_name") = getParam<MooseFunctorName>("thermal_expansion");
414
415 for (const auto d : make_range(dimension()))
416 {
417 params.set<MooseEnum>("momentum_component") = NS::directions[d];
418 params.set<LinearVariableName>("variable") = _velocity_names[d];
419
420 getProblem().addLinearFVKernel(kernel_type, kernel_name + NS::directions[d], params);
421 }
422}
423
424void
426{
427 // Check the size of the BC parameters
428 unsigned int num_velocity_functor_inlets = 0;
429 for (const auto & [bdy, momentum_inlet_type] : _momentum_inlet_types)
430 if (momentum_inlet_type == "fixed-velocity" || momentum_inlet_type == "fixed-pressure")
431 num_velocity_functor_inlets++;
432
433 if (num_velocity_functor_inlets != _momentum_inlet_functors.size())
434 paramError("momentum_inlet_functors",
435 "Size (" + std::to_string(_momentum_inlet_functors.size()) +
436 ") is not the same as the number of entries in the momentum_inlet_types "
437 "subvector for fixed-velocities/pressures functors (size " +
438 std::to_string(num_velocity_functor_inlets) + ")");
439
440 unsigned int velocity_pressure_counter = 0;
441 for (const auto & [inlet_bdy, momentum_inlet_type] : _momentum_inlet_types)
442 {
443 if (momentum_inlet_type == "fixed-velocity")
444 {
445 const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
446 InputParameters params = getFactory().getValidParams(bc_type);
447 params.set<std::vector<BoundaryName>>("boundary") = {inlet_bdy};
448 if (_momentum_inlet_functors.size() < velocity_pressure_counter + 1)
449 paramError("momentum_inlet_functors",
450 "More non-flux inlets than inlet functors (" +
451 std::to_string(_momentum_inlet_functors.size()) + ")");
452
453 // Check that enough functors have been provided for the dimension of the problem
454 const auto momentum_functors = libmesh_map_find(_momentum_inlet_functors, inlet_bdy);
455 if (momentum_functors.size() < dimension())
456 paramError("momentum_inlet_functors",
457 "Subvector for boundary '" + inlet_bdy + "' (size " +
458 std::to_string(momentum_functors.size()) +
459 ") is not the same size as the number of dimensions of the physics (" +
460 std::to_string(dimension()) + ")");
461
462 for (const auto d : make_range(dimension()))
463 {
464 params.set<LinearVariableName>("variable") = _velocity_names[d];
465 params.set<MooseFunctorName>("functor") = momentum_functors[d];
466
467 getProblem().addLinearFVBC(bc_type, _velocity_names[d] + "_" + inlet_bdy, params);
468 }
469 ++velocity_pressure_counter;
470
471 // Add the two term BC expansion for pressure if requested
472 if (getParam<bool>("pressure_two_term_bc_expansion"))
473 {
474 const std::string bc_type = "LinearFVExtrapolatedPressureBC";
475 InputParameters params = getFactory().getValidParams(bc_type);
476 params.set<std::vector<BoundaryName>>("boundary") = {inlet_bdy};
477 params.set<LinearVariableName>("variable") = _pressure_name;
478 params.set<bool>("use_two_term_expansion") = true;
479 getProblem().addLinearFVBC(bc_type,
480 _pressure_name + "_extrapolation_inlet_" +
481 Moose::stringify(inlet_bdy),
482 params);
483 }
484 }
485 else if (momentum_inlet_type == "fixed-pressure")
486 {
487 const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
488 InputParameters params = getFactory().getValidParams(bc_type);
489 params.set<LinearVariableName>("variable") = _pressure_name;
490 if (_momentum_inlet_functors.size() < velocity_pressure_counter + 1)
491 paramError("momentum_inlet_functors",
492 "More non-flux inlets than inlet functors (" +
493 std::to_string(_momentum_inlet_functors.size()) + ")");
494
495 params.set<MooseFunctorName>("functor") =
496 libmesh_map_find(_momentum_inlet_functors, inlet_bdy)[0];
497 params.set<std::vector<BoundaryName>>("boundary") = {inlet_bdy};
498
499 getProblem().addLinearFVBC(bc_type, _pressure_name + "_" + inlet_bdy, params);
500 ++velocity_pressure_counter;
501 }
502 else
503 mooseError("Unsupported inlet boundary condition type: ", momentum_inlet_type);
504 }
505}
506
507void
509{
510 // Check the BCs size
511 unsigned int num_pressure_outlets = 0;
512 for (const auto & [bdy, momentum_outlet_type] : _momentum_outlet_types)
513 if (momentum_outlet_type == "fixed-pressure" ||
514 momentum_outlet_type == "fixed-pressure-zero-gradient")
515 num_pressure_outlets++;
516
517 if (num_pressure_outlets != _pressure_functors.size())
518 paramError("pressure_functors",
519 "Size (" + std::to_string(_pressure_functors.size()) +
520 ") is not the same as the number of pressure outlet boundaries in "
521 "'fixed-pressure/fixed-pressure-zero-gradient' (size " +
522 std::to_string(num_pressure_outlets) + ")");
523
524 const std::string u_names[3] = {"u", "v", "w"};
525 for (const auto & [outlet_bdy, momentum_outlet_type] : _momentum_outlet_types)
526 {
527 // Zero tangeantial gradient condition on velocity
528 if (momentum_outlet_type == "zero-gradient" || momentum_outlet_type == "fixed-pressure" ||
529 momentum_outlet_type == "fixed-pressure-zero-gradient")
530 {
531 const std::string bc_type = "LinearFVAdvectionDiffusionOutflowBC";
532 InputParameters params = getFactory().getValidParams(bc_type);
533 params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
534 params.set<bool>("use_two_term_expansion") = getParam<bool>("momentum_two_term_bc_expansion");
535
536 for (const auto d : make_range(dimension()))
537 {
538 params.set<LinearVariableName>("variable") = _velocity_names[d];
539 getProblem().addLinearFVBC(bc_type, _velocity_names[d] + "_" + outlet_bdy, params);
540 }
541 }
542
543 // Fixed pressure condition, coming in the pressure correction equation
544 if (momentum_outlet_type == "fixed-pressure" ||
545 momentum_outlet_type == "fixed-pressure-zero-gradient")
546 {
547 const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
548 InputParameters params = getFactory().getValidParams(bc_type);
549 params.set<LinearVariableName>("variable") = _pressure_name;
550 params.set<MooseFunctorName>("functor") = libmesh_map_find(_pressure_functors, outlet_bdy);
551 params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
552
553 getProblem().addLinearFVBC(bc_type, _pressure_name + "_" + outlet_bdy, params);
554 }
555 }
556}
557
558void
560{
561 const std::string u_names[3] = {"u", "v", "w"};
562 bool has_symmetry_bc = false;
563
564 for (const auto & [boundary_name, momentum_wall_type] : _momentum_wall_types)
565 {
566 if (momentum_wall_type == "noslip")
567 {
568 const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
569 InputParameters params = getFactory().getValidParams(bc_type);
570 params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
571
572 for (const auto d : make_range(dimension()))
573 {
574 params.set<LinearVariableName>("variable") = _velocity_names[d];
575 if (_momentum_wall_functors.count(boundary_name) == 0)
576 params.set<MooseFunctorName>("functor") = "0";
577 else
578 params.set<MooseFunctorName>("functor") = _momentum_wall_functors[boundary_name][d];
579
580 getProblem().addLinearFVBC(bc_type, _velocity_names[d] + "_" + boundary_name, params);
581 }
582 }
583 else if (momentum_wall_type == "symmetry")
584 {
585 has_symmetry_bc = true;
586 {
587 const std::string bc_type = "LinearFVVelocitySymmetryBC";
588 InputParameters params = getFactory().getValidParams(bc_type);
589 params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
590 for (unsigned int d = 0; d < dimension(); ++d)
591 params.set<SolverVariableName>(u_names[d]) = _velocity_names[d];
592
593 for (const auto d : make_range(dimension()))
594 {
595 params.set<LinearVariableName>("variable") = _velocity_names[d];
596 params.set<MooseEnum>("momentum_component") = NS::directions[d];
597
598 getProblem().addLinearFVBC(bc_type, _velocity_names[d] + "_" + boundary_name, params);
599 }
600 }
601 {
602 const std::string bc_type = "LinearFVPressureSymmetryBC";
603 InputParameters params = getFactory().getValidParams(bc_type);
604 params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
605 params.set<LinearVariableName>("variable") = _pressure_name;
606 params.set<MooseFunctorName>("HbyA_flux") = "HbyA";
607 getProblem().addLinearFVBC(bc_type, _pressure_name + "_" + boundary_name, params);
608 }
609 }
610 else
611 mooseError("Unsupported wall boundary condition type: " + std::string(momentum_wall_type));
612 }
613
614 if (getParam<bool>("pressure_two_term_bc_expansion"))
615 {
616 if (!has_symmetry_bc)
617 {
618 const std::string bc_type = "LinearFVExtrapolatedPressureBC";
619 InputParameters params = getFactory().getValidParams(bc_type);
620 params.set<std::vector<BoundaryName>>("boundary") = _wall_boundaries;
621 params.set<LinearVariableName>("variable") = _pressure_name;
622 params.set<bool>("use_two_term_expansion") = true;
624 bc_type, _pressure_name + "_extrapolation_" + Moose::stringify(_wall_boundaries), params);
625 }
626 else
627 for (const auto & [boundary_name, momentum_wall_type] : _momentum_wall_types)
628 if (momentum_wall_type != "symmetry")
629 {
630 const std::string bc_type = "LinearFVExtrapolatedPressureBC";
631 InputParameters params = getFactory().getValidParams(bc_type);
632 params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
633 params.set<LinearVariableName>("variable") = _pressure_name;
634 params.set<bool>("use_two_term_expansion") = true;
636 bc_type, _pressure_name + "_extrapolation_" + boundary_name, params);
637 }
638 }
639}
640
641void
643{
644 mooseAssert(!_porous_medium_treatment, "Not implemented");
645 // Rhie Chow user object for interpolation velocities
647}
648
649void
651{
652 mooseAssert(dimension(), "0-dimension not supported");
653
654 // First make sure that we only add this object once
655 // Potential cases:
656 // - there is a flow physics, and an advection one (UO should be added by one)
657 // - there is only an advection physics (UO should be created)
658 // - there are two advection physics on different blocks with set velocities (first one picks)
659 // Counting RC UOs defined on the same blocks seems to be the most fool proof option
660 std::vector<UserObject *> objs;
661 getProblem()
662 .theWarehouse()
663 .query()
664 .condition<AttribSystem>("UserObject")
665 .condition<AttribThread>(0)
666 .queryInto(objs);
667 unsigned int num_rc_uo = 0;
668 for (const auto & obj : objs)
669 if (dynamic_cast<RhieChowMassFlux *>(obj))
670 {
671 const auto rc_obj = dynamic_cast<RhieChowMassFlux *>(obj);
672 if (rc_obj->blocks() == _blocks)
673 num_rc_uo++;
674 // one of the RC user object is defined everywhere
675 else if (rc_obj->blocks().size() == 0 || _blocks.size() == 0)
676 num_rc_uo++;
677 }
678
679 if (num_rc_uo)
680 return;
681
682 const std::string u_names[3] = {"u", "v", "w"};
683 const auto object_type = "RhieChowMassFlux";
684
685 auto params = getFactory().getValidParams(object_type);
686 assignBlocks(params, _blocks);
687 for (unsigned int d = 0; d < dimension(); ++d)
688 params.set<VariableName>(u_names[d]) = _velocity_names[d];
689
690 params.set<VariableName>("pressure") = _pressure_name;
691 params.set<std::string>("p_diffusion_kernel") = prefix() + "p_diffusion";
692 params.set<MooseFunctorName>(NS::density) = _density_name;
693 params.set<MooseEnum>("pressure_projection_method") =
694 getParam<MooseEnum>("pressure_projection_method");
695 params.set<MooseEnum>("pressure_diffusion_interpolation") =
696 getParam<MooseEnum>("pressure_diffusion_interpolation");
697
698 addUserObject(object_type, rhieChowUOName(), params);
699}
700
701std::vector<UserObjectName>
706
707void
709{
710 if (parameters().isParamValid("gravity"))
711 {
712 const auto gravity_vector = getParam<RealVectorValue>("gravity");
713 const std::vector<std::string> comp_axis({"x", "y", "z"});
714 for (const auto d : make_range(dimension()))
715 if (gravity_vector(d) != 0)
716 {
717 // Add rho * g functor for each relevant direction
718 // TODO: we could avoid using an AD functor material for non-AD density functor
719 auto params = getFactory().getValidParams("ADParsedFunctorMaterial");
720 assignBlocks(params, _blocks);
721 params.set<std::string>("expression") =
722 _density_gravity_name + " * " + std::to_string(gravity_vector(d));
724 params.set<std::vector<std::string>>("functor_names") = {_density_gravity_name};
725 params.set<std::string>("property_name") = "rho_g_" + comp_axis[d];
726 // We don't output this helper material
728 "ADParsedFunctorMaterial", prefix() + "gravity_helper_" + comp_axis[d], params);
729 }
730 }
731}
732
733unsigned short
registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_interpolation_method_physics")
registerWCNSFVFlowPhysicsBaseTasks("NavierStokesApp", WCNSLinearFVFlowPhysics)
void needSolutionState(unsigned int oldest_needed, Moose::SolutionIterationType iteration_type)
virtual void addLinearFVKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
virtual void addMaterial(const std::string &material_name, const std::string &name, InputParameters &parameters)
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
virtual void addLinearFVBC(const std::string &fv_bc_name, const std::string &name, InputParameters &parameters)
TheWarehouse & theWarehouse() const
InputParameters getValidParams(const std::string &name) const
void suppressParameter(const std::string &name)
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
void renameParam(const std::string &old_name, const std::string &new_name, const std::string &new_docstring)
void transferParam(const InputParameters &source_param, const std::string &name, const std::string &new_name="", const std::string &new_description="")
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
const InputParameters & parameters() const
void paramError(const std::string &param, Args... args) const
bool isParamSetByUser(const std::string &name) const
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
bool _define_variables
Whether to define variables if they do not exist.
void addFVAdvectedInterpolationMethod(const MooseEnum &interpolation_method)
Add the FVInterpolationMethod object for an advected interpolation method if absent.
virtual FEProblemBase & getProblem()
std::vector< SolverSystemName > _system_names
void addUserObject(const std::string &uo_type, const std::string &uo_name, InputParameters &params)
Factory & getFactory()
bool shouldCreateTimeDerivative(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool error_if_already_defined) const
void assignBlocks(InputParameters &params, const std::vector< SubdomainName > &blocks) const
unsigned int dimension() const
void reportPotentiallyMissedParameters(const std::vector< std::string > &param_names, const std::string &object_type, const std::string &object_name="") const
void saveSolverVariableName(const VariableName &var_name)
std::string prefix() const
const SolverSystemName & getSolverSystem(unsigned int variable_index) const
bool shouldCreateVariable(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool error_if_aux)
bool isTransient() const
std::vector< SubdomainName > _blocks
void addRequiredPhysicsTask(const std::string &task)
User object responsible for determining the face fluxes using the Rhie-Chow interpolation in a segreg...
static InputParameters validParams()
Query query()
Base class for Physics which create the Navier Stokes flow equations.
std::map< BoundaryName, MooseEnum > _momentum_outlet_types
Momentum outlet boundary types.
std::vector< std::vector< SubdomainName > > _friction_blocks
Subdomains where we want to have volumetric friction.
static InputParameters validParams()
std::map< BoundaryName, std::vector< MooseFunctorName > > _momentum_wall_functors
Functors describing the momentum for each wall boundary.
std::map< BoundaryName, MooseEnum > _momentum_inlet_types
Momentum inlet boundary types.
std::map< BoundaryName, MooseFunctorName > _pressure_functors
Functors describing the outlet pressure on each boundary.
std::vector< std::vector< std::string > > _friction_types
The friction correlation types used for each block.
const MooseEnum _compressibility
Compressibility type, can be compressible, incompressible or weakly-compressible.
const std::vector< std::string > _velocity_names
Velocity names.
const std::vector< BoundaryName > _wall_boundaries
Boundaries which define a wall (slip/noslip/etc.)
const NonlinearVariableName _pressure_name
Pressure name.
const bool _has_flow_equations
Boolean to keep track of whether the flow equations should be created.
const NonlinearVariableName _fluid_temperature_name
Fluid temperature name.
const bool _porous_medium_treatment
Whether to use the porous medium treatment.
std::map< BoundaryName, std::vector< MooseFunctorName > > _momentum_inlet_functors
Functors describing the momentum inlet for each boundary.
virtual void initializePhysicsAdditional() override
const UserObjectName & rhieChowUOName() const
Return the name of the Rhie Chow user object.
const MooseFunctorName _dynamic_viscosity_name
Name of the dynamic viscosity material property.
std::map< BoundaryName, MooseEnum > _momentum_wall_types
Momentum wall boundary types.
const std::vector< BoundaryName > _hydraulic_separators
Hydraulic separator boundaries.
const bool _solve_for_dynamic_pressure
Whether we are solving for the total or dynamic pressure.
const MooseFunctorName _density_name
Name of the density material property.
const WCNSFVTurbulencePhysicsBase * _turbulence_physics
Can be set to a coupled turbulence physics.
std::vector< std::vector< std::string > > _friction_coeffs
The coefficients used for each item if friction type.
bool includeSymmetrizedViscousStress() const
Whether to include the symmetrized contribution in the viscous stress.
const MooseFunctorName _density_gravity_name
Name of the density material property used for gravity and Boussinesq terms.
Creates all the objects needed to solve the Navier-Stokes equations with the SIMPLE algorithm using t...
virtual void addUserObjects() override
virtual void addSolverVariables() override
virtual void addMomentumPressureKernels() override
virtual void addRhieChowUserObjects() override
Function which adds the RhieChow interpolator user objects for weakly and incompressible formulations...
void addMomentumTimeKernels() override
Functions adding kernels for the incompressible momentum equation If the material properties are not ...
virtual void initializePhysicsAdditional() override
unsigned short getNumberAlgebraicGhostingLayersNeeded() const override
Return the number of algebraic ghosting layers needed.
virtual void addMomentumBoussinesqKernels() override
WCNSLinearFVFlowPhysics(const InputParameters &parameters)
virtual void addInletBC() override
Functions adding boundary conditions for the flow simulation.
virtual void addFVKernels() override
static InputParameters validParams()
virtual void addMomentumFrictionKernels() override
virtual std::vector< UserObjectName > getSuppliedUserObjects() const override
virtual void addOutletBC() override
virtual void addFVInterpolationMethods() override
virtual void addMomentumGravityKernels() override
virtual void addWallsBC() override
void addPressureCorrectionKernels()
Function adding kernels for the incompressible pressure correction equation.
const bool _non_orthogonal_correction
Whether to use the correction term for non-orthogonality.
virtual void addFunctorMaterials() override
std::string toUpper(std::string name)
bool parsesToReal(const std::string &input, Real *parsed_real)
std::string stringify(const T &t)
static const std::string density
Definition NS.h:34
static const std::string T_fluid
Definition NS.h:110
MooseEnum fvFaceInterpolationMethods()
Enum of the interpolation methods supported by FVInterpolationMethod objects.
Definition NSFVUtils.C:85
static const std::string mu
Definition NS.h:127
static const std::string directions[3]
Definition NS.h:23
static const std::string mu_eff
Definition NS.h:133
MooseEnum fvAdvectedInterpolationMethods()
Enum of the advected interpolation methods supported by FVInterpolationMethod objects.
Definition NSFVUtils.C:61