https://mooseframework.inl.gov
Loading...
Searching...
No Matches
WCNSFVFlowPhysics.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
10#include "WCNSFVFlowPhysics.h"
12#include "NSFVBase.h"
15#include "INSFVTimeKernel.h"
16#include "MapConversionUtils.h"
17#include "NS.h"
18
20registerMooseAction("NavierStokesApp", WCNSFVFlowPhysics, "add_fv_kernel");
21registerMooseAction("NavierStokesApp", WCNSFVFlowPhysics, "add_fv_bc");
22
25{
28 "Define the Navier Stokes weakly-compressible mass and momentum equations");
29
30 // Rhie Chow interpolation parameters
31 params.transferParam<Real>(INSFVMomentumAdvection::validParams(), "characteristic_speed");
32 params.addParam<bool>(
33 "time_derivative_contributes_to_RC_coefficients",
34 true,
35 "Whether the time derivative term should contribute to the Rhie Chow coefficients. This adds "
36 "stabilization, but makes the solution dependent on the time step size");
37 params.addParamNamesToGroup("time_derivative_contributes_to_RC_coefficients characteristic_speed",
38 "Numerical scheme");
39
40 // Used for flow mixtures, where one phase is solid / not moving under the action of gravity
41 params.addParam<MooseFunctorName>(
42 "density_for_gravity_terms",
43 "If specified, replaces the 'density' for the Boussinesq and gravity momentum kernels");
44
45 // Additional porous media parameters
46 params.transferParam<unsigned short>(NSFVBase::validParams(), "porosity_smoothing_layers");
47
48 // Techniques to limit or remove oscillations at porosity jump interfaces
49 params.transferParam<MooseEnum>(NSFVBase::validParams(), "porosity_interface_pressure_treatment");
50 params.transferParam<std::vector<BoundaryName>>(NSFVBase::validParams(),
51 "pressure_drop_sidesets");
52 params.transferParam<std::vector<Real>>(NSFVBase::validParams(), "pressure_drop_form_factors");
53
54 // Friction correction, a technique to limit oscillations at friction interfaces
55 params.transferParam<bool>(NSFVBase::validParams(), "use_friction_correction");
56 params.transferParam<Real>(NSFVBase::validParams(), "consistent_scaling");
57
58 // Couple to turbulence physics
59 params.addParam<PhysicsName>("coupled_turbulence_physics",
60 "Turbulence Physics coupled with the flow");
61
62 // Spatial discretization scheme
63 // Specify the numerical schemes for interpolations of velocity and pressure
64 params.transferParam<MooseEnum>(NSFVBase::validParams(), "pressure_face_interpolation");
65 params.transferParam<MooseEnum>(NSFVBase::validParams(), "mass_advection_interpolation");
67 "pressure_allow_expansion_on_bernoulli_faces");
68
69 // Nonlinear solver parameters
70 params.transferParam<Real>(NSFVBase::validParams(), "mass_scaling");
71 params.transferParam<Real>(NSFVBase::validParams(), "momentum_scaling");
72
73 // Parameter groups
74 params.addParamNamesToGroup("coupled_turbulence_physics", "Coupled Physics");
76 "porosity_interface_pressure_treatment pressure_allow_expansion_on_bernoulli_faces "
77 "porosity_smoothing_layers use_friction_correction consistent_scaling "
78 "pressure_drop_sidesets pressure_drop_form_factors",
79 "Flow medium discontinuity treatment");
81 "pressure_face_interpolation mass_advection_interpolation mass_scaling momentum_scaling",
82 "Numerical scheme");
83
84 // TODO Add default preconditioning and move scaling parameters to a preconditioning group
85
86 return params;
87}
88
90 : WCNSFVFlowPhysicsBase(parameters),
91 _porosity_smoothing_layers(isParamValid("porosity_smoothing_layers")
92 ? getParam<unsigned short>("porosity_smoothing_layers")
93 : 0)
94{
95 _flow_porosity_functor_name = isParamValid("porosity_smoothing_layers") &&
96 getParam<unsigned short>("porosity_smoothing_layers")
99
100 // Most likely to be a mistake
101 if (getParam<bool>("pin_pressure") &&
102 getParam<std::vector<MooseFunctorName>>("pressure_functors").size())
103 paramError("pin_pressure", "Cannot pin the pressure if a pressure boundary exists");
104
105 // Pressure pin checks
106 checkSecondParamSetOnlyIfFirstOneTrue("pin_pressure", "pinned_pressure_type");
107 checkSecondParamSetOnlyIfFirstOneTrue("pin_pressure", "pinned_pressure_value");
108 if (getParam<bool>("pin_pressure"))
109 {
110 if ((std::string(getParam<MooseEnum>("pinned_pressure_type")).find("point") !=
111 std::string::npos) &&
112 !isParamSetByUser("pinned_pressure_point"))
113 paramError("pinned_pressure_point",
114 "This parameter must be set to specify the pinned pressure point");
115 else if ((std::string(getParam<MooseEnum>("pinned_pressure_type")).find("point") ==
116 std::string::npos) &&
117 isParamSetByUser("pinned_pressure_point"))
118 paramError("pinned_pressure_point",
119 "This parameter should not be given by the user with the corresponding "
120 "pinned_pressure_type setting: " +
121 std::string(getParam<MooseEnum>("pinned_pressure_type")) + ".");
122 }
123
124 // Porosity correction checks
125 checkSecondParamSetOnlyIfFirstOneTrue("porous_medium_treatment", "use_friction_correction");
126 checkSecondParamSetOnlyIfFirstOneTrue("use_friction_correction", "consistent_scaling");
127 checkSecondParamSetOnlyIfFirstOneTrue("porous_medium_treatment",
128 "porosity_interface_pressure_treatment");
129 if (getParam<MooseEnum>("porosity_interface_pressure_treatment") != "bernoulli")
130 errorDependentParameter("porosity_interface_pressure_treatment",
131 "bernoulli",
132 {"pressure_allow_expansion_on_bernoulli_faces",
133 "pressure_drop_sidesets",
134 "pressure_drop_form_factors"});
135
136 // Porous media parameters
137 checkSecondParamSetOnlyIfFirstOneTrue("porous_medium_treatment", "porosity_smoothing_layers");
138}
139
140void
142{
144 return;
145
146 for (const auto d : make_range(dimension()))
149
150 // Check number of variables
151 if (_velocity_names.size() != dimension() && _velocity_names.size() != 3)
152 paramError("velocity_variable",
153 "The number of velocity variable names supplied to the NSFVAction is not " +
154 Moose::stringify(dimension()) + " (mesh dimension)" +
155 ((dimension() == 3) ? "" : " or 3!") + "\nVelocity variables " +
157
158 // Velocities
159 for (const auto d : make_range(dimension()))
160 {
161 if (!shouldCreateVariable(_velocity_names[d], _blocks, /*error if aux*/ true))
162 reportPotentiallyMissedParameters({"system_names",
163 "momentum_scaling",
164 "momentum_face_interpolation",
165 "momentum_two_term_bc_expansion"},
166 "INSFVVelocityVariable");
167 else if (_define_variables)
168 {
169 std::string variable_type = "INSFVVelocityVariable";
171 variable_type = "PINSFVSuperficialVelocityVariable";
172
173 auto params = getFactory().getValidParams(variable_type);
174 params.set<std::vector<Real>>("scaling") = {getParam<Real>("momentum_scaling")};
175 params.set<MooseEnum>("face_interp_method") =
176 getParam<MooseEnum>("momentum_face_interpolation");
177 params.set<bool>("two_term_boundary_expansion") =
178 getParam<bool>("momentum_two_term_bc_expansion");
179
180 // TODO: check wrt components
181 addSharedSolverVariable(variable_type, _velocity_names[d], params);
182 }
183 else
184 paramError("velocity_variable",
185 "Variable (" + _velocity_names[d] +
186 ") supplied to the WCNSFVFlowPhysics does not exist!");
187 }
188
189 // Pressure
190 const bool using_bernouilli_pressure_var =
192 getParam<MooseEnum>("porosity_interface_pressure_treatment") != "automatic";
193 const auto pressure_type =
194 using_bernouilli_pressure_var ? "BernoulliPressureVariable" : "INSFVPressureVariable";
195 if (!shouldCreateVariable(_pressure_name, _blocks, /*error if aux*/ true))
196 {
197 std::vector<std::string> potentially_missed = {"system_names",
198 "mass_scaling",
199 "pressure_face_interpolation",
200 "pressure_two_term_bc_expansion"};
201 if (using_bernouilli_pressure_var)
202 {
203 std::vector<std::string> other_missed = {"pressure_allow_expansion_on_bernoulli_faces",
204 "pressure_drop_sidesets",
205 "pressure_drop_form_factors"};
206 potentially_missed.insert(potentially_missed.end(), other_missed.begin(), other_missed.end());
207 }
208 reportPotentiallyMissedParameters(potentially_missed, pressure_type);
209 }
210 else if (_define_variables)
211 {
212 auto params = getFactory().getValidParams(pressure_type);
213 params.set<std::vector<Real>>("scaling") = {getParam<Real>("mass_scaling")};
214 params.set<MooseEnum>("face_interp_method") =
215 getParam<MooseEnum>("pressure_face_interpolation");
216 params.set<bool>("two_term_boundary_expansion") =
217 getParam<bool>("pressure_two_term_bc_expansion");
218
219 if (using_bernouilli_pressure_var)
220 {
221 params.set<MooseFunctorName>("u") = _velocity_names[0];
222 if (dimension() >= 2)
223 params.set<MooseFunctorName>("v") = _velocity_names[1];
224 if (dimension() == 3)
225 params.set<MooseFunctorName>("w") = _velocity_names[2];
226 params.set<MooseFunctorName>(NS::porosity) = _porosity_name;
227 params.set<MooseFunctorName>(NS::density) = _density_name;
228 params.set<bool>("allow_two_term_expansion_on_bernoulli_faces") =
229 getParam<bool>("pressure_allow_expansion_on_bernoulli_faces");
230 params.set<std::vector<BoundaryName>>("pressure_drop_sidesets") =
231 getParam<std::vector<BoundaryName>>("pressure_drop_sidesets");
232 params.set<std::vector<Real>>("pressure_drop_form_factors") =
233 getParam<std::vector<Real>>("pressure_drop_form_factors");
234 }
235 addSharedSolverVariable(pressure_type, _pressure_name, params);
236 }
237 else
238 paramError("pressure_variable",
239 "Variable (" + _pressure_name +
240 ") supplied to the WCNSFVFlowPhysics does not exist!");
241
242 // Add lagrange multiplier for pinning pressure, if needed
243 if (getParam<bool>("pin_pressure"))
244 {
245 auto type = getParam<MooseEnum>("pinned_pressure_type");
246 auto lm_params = getFactory().getValidParams("MooseVariableScalar");
247 lm_params.set<MooseEnum>("family") = "scalar";
248 lm_params.set<MooseEnum>("order") = "first";
249
250 if ((type == "point-value" || type == "average"))
251 {
252 if (!_problem->hasScalarVariable("lambda"))
253 {
254 lm_params.set<SolverSystemName>("solver_sys") = getSolverSystem("lambda");
255 getProblem().addVariable("MooseVariableScalar", "lambda", lm_params);
256 }
257 else
258 reportPotentiallyMissedParameters({"system_names"}, "MooseVariableScalar");
259 }
260 }
261}
262
263void
265{
267 return;
268
269 // Mass equation: time derivative
270 if (_compressibility == "weakly-compressible" &&
271 shouldCreateTimeDerivative(_pressure_name, _blocks, /*error if already defined*/ false))
273
274 // Mass equation: divergence of momentum
276
277 // Pressure pin
278 if (getParam<bool>("pin_pressure"))
280
281 // Momentum equation: time derivative
282 if (isTransient())
284
285 // Momentum equation: momentum advection
287
288 // Momentum equation: momentum viscous stress
291
292 // Momentum equation: pressure term
294
295 // Momentum equation: gravity source term
297
298 // Momentum equation: friction kernels
299 if (_friction_types.size())
301
302 // Momentum equation: boussinesq approximation
303 if (getParam<bool>("boussinesq_approximation"))
305}
306
307void
309{
310 std::string mass_kernel_type = "WCNSFVMassTimeDerivative";
311 std::string kernel_name = prefix() + "wcns_mass_time";
312
314 {
315 mass_kernel_type = "PWCNSFVMassTimeDerivative";
316 kernel_name = prefix() + "pwcns_mass_time";
317 }
318
319 InputParameters params = getFactory().getValidParams(mass_kernel_type);
320 assignBlocks(params, _blocks);
321 params.set<NonlinearVariableName>("variable") = _pressure_name;
322 params.set<MooseFunctorName>(NS::time_deriv(NS::density)) = NS::time_deriv(_density_name);
324 params.set<MooseFunctorName>(NS::porosity) = _flow_porosity_functor_name;
325 getProblem().addFVKernel(mass_kernel_type, kernel_name, params);
326}
327
328void
330{
331 std::string kernel_type = "INSFVMassAdvection";
332 std::string kernel_name = prefix() + "ins_mass_advection";
333
335 {
336 kernel_type = "PINSFVMassAdvection";
337 kernel_name = prefix() + "pins_mass_advection";
338 }
339
340 InputParameters params = getFactory().getValidParams(kernel_type);
341 assignBlocks(params, _blocks);
342 params.set<NonlinearVariableName>("variable") = _pressure_name;
343 params.set<MooseFunctorName>(NS::density) = _density_name;
344 params.set<MooseEnum>("velocity_interp_method") = _velocity_interpolation;
345 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
346 params.set<MooseEnum>("advected_interp_method") =
347 getParam<MooseEnum>("mass_advection_interpolation");
348
349 getProblem().addFVKernel(kernel_type, kernel_name, params);
350}
351
352void
354{
355 const auto pin_type = getParam<MooseEnum>("pinned_pressure_type");
356 const auto object_type =
357 (pin_type == "average") ? "FVIntegralValueConstraint" : "FVPointValueConstraint";
358 InputParameters params = getFactory().getValidParams(object_type);
359 if (pin_type != "point-value" && pin_type != "average")
360 return;
361
362 params.set<CoupledName>("lambda") = {"lambda"};
363 params.set<PostprocessorName>("phi0") = getParam<PostprocessorName>("pinned_pressure_value");
364 params.set<NonlinearVariableName>("variable") = _pressure_name;
365 if (pin_type == "point-value")
366 params.set<Point>("point") = getParam<Point>("pinned_pressure_point");
367
368 getProblem().addFVKernel(object_type, prefix() + "ins_mass_pressure_pin", params);
369}
370
371void
373{
374 std::string kernel_type = (_compressibility == "weakly-compressible")
375 ? "WCNSFVMomentumTimeDerivative"
376 : "INSFVMomentumTimeDerivative";
377 std::string kernel_name = prefix() +
378 ((_compressibility == "weakly-compressible") ? "wcns_" : "ins_") +
379 "momentum_time_";
380
382 {
383 // Porosity does not appear in the term
384 kernel_type = (_compressibility == "weakly-compressible") ? "WCNSFVMomentumTimeDerivative"
385 : "PINSFVMomentumTimeDerivative";
386 kernel_name = prefix() + ((_compressibility == "weakly-compressible") ? "pwcns_" : "pins_") +
387 "momentum_time_";
388 }
389
390 InputParameters params = getFactory().getValidParams(kernel_type);
391 assignBlocks(params, _blocks);
392 params.set<MooseFunctorName>(NS::density) = _density_name;
393 if (_compressibility == "weakly-compressible")
394 params.set<MooseFunctorName>(NS::time_deriv(NS::density)) = NS::time_deriv(_density_name);
395
396 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
397 params.set<bool>("contribute_to_rc") =
398 getParam<bool>("time_derivative_contributes_to_RC_coefficients");
399
400 for (const auto d : make_range(dimension()))
401 {
402 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
403 params.set<MooseEnum>("momentum_component") = NS::directions[d];
404
405 if (shouldCreateTimeDerivative(_velocity_names[d], _blocks, /*error if already defined*/ false))
406 getProblem().addFVKernel(kernel_type, kernel_name + _velocity_names[d], params);
407 }
408}
409
410void
412{
413 std::string kernel_type = "INSFVMomentumAdvection";
414 std::string kernel_name = prefix() + "ins_momentum_advection_";
415
417 {
418 kernel_type = "PINSFVMomentumAdvection";
419 kernel_name = prefix() + "pins_momentum_advection_";
420 }
421
422 InputParameters params = getFactory().getValidParams(kernel_type);
423 assignBlocks(params, _blocks);
424 params.set<MooseFunctorName>(NS::density) = _density_name;
425 params.set<MooseEnum>("velocity_interp_method") = _velocity_interpolation;
426 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
427 params.set<MooseEnum>("advected_interp_method") = _momentum_advection_interpolation;
429 params.set<MooseFunctorName>(NS::porosity) = _flow_porosity_functor_name;
431
432 for (const auto d : make_range(dimension()))
433 {
434 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
435 params.set<MooseEnum>("momentum_component") = NS::directions[d];
436
437 getProblem().addFVKernel(kernel_type, kernel_name + NS::directions[d], params);
438 }
439}
440
441void
443{
444 std::string kernel_type = "INSFVMomentumDiffusion";
445 std::string kernel_name = prefix() + "ins_momentum_diffusion_";
446
448 {
449 kernel_type = "PINSFVMomentumDiffusion";
450 kernel_name = prefix() + "pins_momentum_diffusion_";
451 }
452
453 InputParameters params = getFactory().getValidParams(kernel_type);
454 assignBlocks(params, _blocks);
455 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
456 params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
457 const bool user_include_iso = includeIsotropicStress();
458 if (user_include_iso && _porous_medium_treatment)
459 paramWarning("include_isotropic_viscous_stress",
460 "Including the isotropic viscous stress is not supported with the porous medium "
461 "treatment. Ignoring the request.");
462 const bool include_isotropic = (!_porous_medium_treatment) && user_include_iso;
463 if (include_isotropic)
464 params.set<bool>("include_isotropic_viscous_stress") = true;
465 params.set<MooseEnum>("mu_interp_method") = getParam<MooseEnum>("mu_interp_method");
466 params.set<MooseEnum>("variable_interp_method") =
467 getParam<MooseEnum>("momentum_face_interpolation");
468 bool include_symmetric = includeSymmetrizedViscousStress();
469 if (include_symmetric && _porous_medium_treatment)
470 {
471 paramWarning("include_symmetrized_viscous_stress",
472 "Including the symmetrized viscous stress is not supported with the porous "
473 "medium treatment. Ignoring the request.");
474 include_symmetric = false;
475 }
476 if (include_symmetric || include_isotropic)
477 {
478 params.set<bool>("complete_expansion") = true;
479 const std::string u_names[3] = {"u", "v", "w"};
480 for (unsigned int i = 0; i < dimension(); ++i)
481 params.set<MooseFunctorName>(u_names[i]) = _velocity_names[i];
482 }
483
485 params.set<MooseFunctorName>(NS::porosity) = _flow_porosity_functor_name;
486 // Currently only Newton method for WCNSFVFlowPhysics
487 params.set<bool>("newton_solve") = true;
488 for (const auto d : make_range(dimension()))
489 {
490 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
491 params.set<MooseEnum>("momentum_component") = NS::directions[d];
492
493 getProblem().addFVKernel(kernel_type, kernel_name + NS::directions[d], params);
494 }
495}
496
497void
498WCNSFVFlowPhysics::addAxisymmetricViscousSourceKernel(const std::vector<SubdomainName> & rz_blocks,
499 const unsigned int radial_index)
500{
501 InputParameters params = getFactory().getValidParams("INSFVMomentumViscousSourceRZ");
502 assignBlocks(params, rz_blocks);
503 params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
504 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
505 params.set<MooseEnum>("momentum_component") = NS::directions[radial_index];
506 params.set<bool>("complete_expansion") = includeSymmetrizedViscousStress();
507 params.set<NonlinearVariableName>("variable") = _velocity_names[radial_index];
508
509 getProblem().addFVKernel("INSFVMomentumViscousSourceRZ",
510 prefix() + "ins_momentum_viscous_source_rz_" +
511 NS::directions[radial_index],
512 params);
513}
514
515void
517{
518 std::string kernel_type = "INSFVMomentumPressure";
519 std::string kernel_name = prefix() + "ins_momentum_pressure_";
520
522 {
523 kernel_type = "PINSFVMomentumPressure";
524 kernel_name = prefix() + "pins_momentum_pressure_";
525 }
526
527 InputParameters params = getFactory().getValidParams(kernel_type);
528 assignBlocks(params, _blocks);
529 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
530 params.set<MooseFunctorName>("pressure") = _pressure_name;
531 params.set<bool>("correct_skewness") =
532 getParam<MooseEnum>("pressure_face_interpolation") == "skewness-corrected";
534 params.set<MooseFunctorName>(NS::porosity) = _flow_porosity_functor_name;
535
536 for (const auto d : make_range(dimension()))
537 {
538 params.set<MooseEnum>("momentum_component") = NS::directions[d];
539 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
540 getProblem().addFVKernel(kernel_type, kernel_name + NS::directions[d], params);
541 }
542}
543
544void
546{
548 {
549 std::string kernel_type = "INSFVMomentumGravity";
550 std::string kernel_name = prefix() + "ins_momentum_gravity_";
551
553 {
554 kernel_type = "PINSFVMomentumGravity";
555 kernel_name = prefix() + "pins_momentum_gravity_";
556 }
557
558 InputParameters params = getFactory().getValidParams(kernel_type);
559 assignBlocks(params, _blocks);
560 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
561 params.set<MooseFunctorName>(NS::density) = _density_gravity_name;
562 params.set<RealVectorValue>("gravity") = getParam<RealVectorValue>("gravity");
564 params.set<MooseFunctorName>(NS::porosity) = _flow_porosity_functor_name;
565
566 for (const auto d : make_range(dimension()))
567 {
568 if (getParam<RealVectorValue>("gravity")(d) != 0)
569 {
570 params.set<MooseEnum>("momentum_component") = NS::directions[d];
571 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
572
573 getProblem().addFVKernel(kernel_type, kernel_name + NS::directions[d], params);
574 }
575 }
576 }
577}
578
579void
581{
582 if (_compressibility == "weakly-compressible")
583 paramError("boussinesq_approximation",
584 "We cannot use boussinesq approximation while running in weakly-compressible mode!");
585
586 std::string kernel_type = "INSFVMomentumBoussinesq";
587 std::string kernel_name = prefix() + "ins_momentum_boussinesq_";
588
590 {
591 kernel_type = "PINSFVMomentumBoussinesq";
592 kernel_name = prefix() + "pins_momentum_boussinesq_";
593 }
594
595 InputParameters params = getFactory().getValidParams(kernel_type);
596 assignBlocks(params, _blocks);
597 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
598 params.set<MooseFunctorName>(NS::T_fluid) = _fluid_temperature_name;
599 params.set<MooseFunctorName>(NS::density) = _density_gravity_name;
600 params.set<RealVectorValue>("gravity") = getParam<RealVectorValue>("gravity");
601 params.set<Real>("ref_temperature") = getParam<Real>("ref_temperature");
602 params.set<MooseFunctorName>("alpha_name") = getParam<MooseFunctorName>("thermal_expansion");
604 params.set<MooseFunctorName>(NS::porosity) = _flow_porosity_functor_name;
605 // User declared the flow to be incompressible, we have to trust them
606 params.set<bool>("_override_constant_check") = true;
607
608 for (const auto d : make_range(dimension()))
609 {
610 if (getParam<RealVectorValue>("gravity")(d) != 0)
611 {
612 params.set<MooseEnum>("momentum_component") = NS::directions[d];
613 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
614
615 getProblem().addFVKernel(kernel_type, kernel_name + NS::directions[d], params);
616 }
617 }
618}
619
620void
622{
623 unsigned int num_friction_blocks = _friction_blocks.size();
624 unsigned int num_used_blocks = num_friction_blocks ? num_friction_blocks : 1;
625
626 const std::string kernel_type = "PINSFVMomentumFriction";
627 InputParameters params = getFactory().getValidParams(kernel_type);
628 params.set<MooseFunctorName>(NS::density) = _density_name;
629 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
631 params.set<MooseFunctorName>(NS::speed) = NS::speed;
632 params.set<bool>("standard_friction_formulation") =
633 getParam<bool>("standard_friction_formulation");
634 params.set<bool>("is_porous_medium") = _porous_medium_treatment;
635
636 for (const auto block_i : make_range(num_used_blocks))
637 {
638 std::string block_name = "";
639 if (num_friction_blocks)
640 {
641 params.set<std::vector<SubdomainName>>("block") = _friction_blocks[block_i];
642 block_name = Moose::stringify(_friction_blocks[block_i]);
643 }
644 else
645 {
646 assignBlocks(params, _blocks);
647 block_name = std::to_string(block_i);
648 }
649
650 for (const auto d : make_range(dimension()))
651 {
652 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
653 params.set<MooseEnum>("momentum_component") = NS::directions[d];
654 for (unsigned int type_i = 0; type_i < _friction_types[block_i].size(); ++type_i)
655 {
656 const auto upper_name = MooseUtils::toUpper(_friction_types[block_i][type_i]);
657 if (upper_name == "DARCY")
658 {
659 params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
660 params.set<MooseFunctorName>("Darcy_name") = _friction_coeffs[block_i][type_i];
661 }
662 else if (upper_name == "FORCHHEIMER")
663 {
664 params.set<MooseFunctorName>(NS::speed) = NS::speed;
665 params.set<MooseFunctorName>("Forchheimer_name") = _friction_coeffs[block_i][type_i];
666 }
667 else
668 paramError("friction_types",
669 "Friction type '",
670 _friction_types[block_i][type_i],
671 "' is not implemented");
672 }
673
674 getProblem().addFVKernel(kernel_type,
675 prefix() + "momentum_friction_" + block_name + "_" +
677 params);
678 }
679
680 if (_porous_medium_treatment && getParam<bool>("use_friction_correction"))
681 {
682 const std::string correction_kernel_type = "PINSFVMomentumFrictionCorrection";
683 InputParameters corr_params = getFactory().getValidParams(correction_kernel_type);
684 if (num_friction_blocks)
685 corr_params.set<std::vector<SubdomainName>>("block") = _friction_blocks[block_i];
686 else
687 assignBlocks(corr_params, _blocks);
688 corr_params.set<MooseFunctorName>(NS::density) = _density_name;
689 corr_params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
690 corr_params.set<Real>("consistent_scaling") = getParam<Real>("consistent_scaling");
691 for (const auto d : make_range(dimension()))
692 {
693 corr_params.set<NonlinearVariableName>("variable") = _velocity_names[d];
694 corr_params.set<MooseEnum>("momentum_component") = NS::directions[d];
695 for (unsigned int type_i = 0; type_i < _friction_types[block_i].size(); ++type_i)
696 {
697 const auto upper_name = MooseUtils::toUpper(_friction_types[block_i][type_i]);
698 if (upper_name == "DARCY")
699 {
700 corr_params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
701 corr_params.set<MooseFunctorName>("Darcy_name") = _friction_coeffs[block_i][type_i];
702 }
703 else if (upper_name == "FORCHHEIMER")
704 {
705 corr_params.set<MooseFunctorName>(NS::speed) = NS::speed;
706 corr_params.set<MooseFunctorName>("Forchheimer_name") =
707 _friction_coeffs[block_i][type_i];
708 }
709 }
710
711 getProblem().addFVKernel(correction_kernel_type,
712 prefix() + "pins_momentum_friction_correction_" + block_name +
713 "_" + NS::directions[d],
714 corr_params);
715 }
716 }
717 }
718}
719
720void
722{
723 // Check the size of the BC parameters
724 unsigned int num_velocity_functor_inlets = 0;
725 for (const auto & [bdy, momentum_outlet_type] : _momentum_inlet_types)
726 if (momentum_outlet_type == "fixed-velocity" || momentum_outlet_type == "fixed-pressure")
727 num_velocity_functor_inlets++;
728
729 if (num_velocity_functor_inlets != _momentum_inlet_functors.size())
730 paramError("momentum_inlet_functors",
731 "Size (" + std::to_string(_momentum_inlet_functors.size()) +
732 ") is not the same as the number of entries in the momentum_inlet_types "
733 "subvector for fixed-velocities/pressures functors (size " +
734 std::to_string(num_velocity_functor_inlets) + ")");
735
736 unsigned int flux_bc_counter = 0;
737 unsigned int velocity_pressure_counter = 0;
738 for (const auto & [inlet_bdy, momentum_inlet_type] : _momentum_inlet_types)
739 {
740 if (momentum_inlet_type == "fixed-velocity")
741 {
742 const std::string bc_type = "INSFVInletVelocityBC";
743 InputParameters params = getFactory().getValidParams(bc_type);
744 params.set<std::vector<BoundaryName>>("boundary") = {inlet_bdy};
745 if (_momentum_inlet_functors.size() < velocity_pressure_counter + 1)
746 paramError("momentum_inlet_functors",
747 "More non-flux inlets than inlet functors (" +
748 std::to_string(_momentum_inlet_functors.size()) + ")");
749
750 // Check that enough functors have been provided for the dimension of the problem
751 const auto momentum_functors = libmesh_map_find(_momentum_inlet_functors, inlet_bdy);
752 if (momentum_functors.size() < dimension())
753 paramError("momentum_inlet_functors",
754 "Subvector for boundary '" + inlet_bdy + "' (size " +
755 std::to_string(momentum_functors.size()) +
756 ") is not the same size as the number of dimensions of the physics (" +
757 std::to_string(dimension()) + ")");
758
759 for (const auto d : make_range(dimension()))
760 {
761 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
762 params.set<MooseFunctorName>("functor") = momentum_functors[d];
763
764 getProblem().addFVBC(bc_type, _velocity_names[d] + "_" + inlet_bdy, params);
765 }
766 ++velocity_pressure_counter;
767 }
768 else if (momentum_inlet_type == "fixed-pressure")
769 {
770 const std::string bc_type = "INSFVOutletPressureBC";
771 InputParameters params = getFactory().getValidParams(bc_type);
772 params.set<NonlinearVariableName>("variable") = _pressure_name;
773 if (_momentum_inlet_functors.size() < velocity_pressure_counter + 1)
774 paramError("momentum_inlet_functors",
775 "More non-flux inlets than inlet functors (" +
776 std::to_string(_momentum_inlet_functors.size()) + ")");
777
778 params.set<FunctionName>("function") =
779 libmesh_map_find(_momentum_inlet_functors, inlet_bdy)[0];
780 params.set<std::vector<BoundaryName>>("boundary") = {inlet_bdy};
781
782 getProblem().addFVBC(bc_type, _pressure_name + "_" + inlet_bdy, params);
783 ++velocity_pressure_counter;
784 }
785 else if (momentum_inlet_type == "flux-mass" || momentum_inlet_type == "flux-velocity")
786 {
787 {
788 const std::string bc_type =
789 _porous_medium_treatment ? "PWCNSFVMomentumFluxBC" : "WCNSFVMomentumFluxBC";
790 InputParameters params = getFactory().getValidParams(bc_type);
791
792 if (_flux_inlet_directions.size())
793 params.set<Point>("direction") = _flux_inlet_directions[flux_bc_counter];
794
795 params.set<MooseFunctorName>(NS::density) = _density_name;
796 params.set<std::vector<BoundaryName>>("boundary") = {inlet_bdy};
797 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
799 params.set<MooseFunctorName>(NS::porosity) = _porosity_name;
800 if (_flux_inlet_pps.size() < flux_bc_counter + 1)
801 paramError("flux_inlet_pps",
802 "More inlet flux BCs than inlet flux pps (" +
803 std::to_string(_flux_inlet_pps.size()) + ")");
804
805 if (momentum_inlet_type == "flux-mass")
806 {
807 params.set<PostprocessorName>("mdot_pp") = _flux_inlet_pps[flux_bc_counter];
808 params.set<PostprocessorName>("area_pp") = "area_pp_" + inlet_bdy;
809 }
810 else
811 params.set<PostprocessorName>("velocity_pp") = _flux_inlet_pps[flux_bc_counter];
812
813 for (const auto d : make_range(dimension()))
814 params.set<MooseFunctorName>(NS::velocity_vector[d]) = _velocity_names[d];
815
816 for (const auto d : make_range(dimension()))
817 {
818 params.set<MooseEnum>("momentum_component") = NS::directions[d];
819 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
820
821 getProblem().addFVBC(bc_type, _velocity_names[d] + "_" + inlet_bdy, params);
822 }
823 }
824 {
825 const std::string bc_type = "WCNSFVMassFluxBC";
826 InputParameters params = getFactory().getValidParams(bc_type);
827 params.set<MooseFunctorName>(NS::density) = _density_name;
828 params.set<NonlinearVariableName>("variable") = _pressure_name;
829 params.set<std::vector<BoundaryName>>("boundary") = {inlet_bdy};
830
831 if (_flux_inlet_directions.size())
832 params.set<Point>("direction") = _flux_inlet_directions[flux_bc_counter];
833
834 if (momentum_inlet_type == "flux-mass")
835 {
836 params.set<PostprocessorName>("mdot_pp") = _flux_inlet_pps[flux_bc_counter];
837 params.set<PostprocessorName>("area_pp") = "area_pp_" + inlet_bdy;
838 }
839 else
840 params.set<PostprocessorName>("velocity_pp") = _flux_inlet_pps[flux_bc_counter];
841
842 for (const auto d : make_range(dimension()))
843 params.set<MooseFunctorName>(NS::velocity_vector[d]) = _velocity_names[d];
844
845 getProblem().addFVBC(bc_type, _pressure_name + "_" + inlet_bdy, params);
846 }
847
848 // need to increment flux_bc_counter
849 ++flux_bc_counter;
850 }
851 }
852}
853
854void
856{
857 // Check the BCs size
858 unsigned int num_pressure_outlets = 0;
859 for (const auto & [bdy, momentum_outlet_type] : _momentum_outlet_types)
860 if (momentum_outlet_type == "fixed-pressure" ||
861 momentum_outlet_type == "fixed-pressure-zero-gradient")
862 num_pressure_outlets++;
863
864 if (num_pressure_outlets != _pressure_functors.size())
865 paramError("pressure_functors",
866 "Size (" + std::to_string(_pressure_functors.size()) +
867 ") is not the same as the number of pressure outlet boundaries in "
868 "'fixed-pressure/fixed-pressure-zero-gradient' (size " +
869 std::to_string(num_pressure_outlets) + ")");
870
871 const std::string u_names[3] = {"u", "v", "w"};
872 for (const auto & [outlet_bdy, momentum_outlet_type] : _momentum_outlet_types)
873 {
874 if (momentum_outlet_type == "zero-gradient" ||
875 momentum_outlet_type == "fixed-pressure-zero-gradient")
876 {
877 {
878 const std::string bc_type = _porous_medium_treatment ? "PINSFVMomentumAdvectionOutflowBC"
879 : "INSFVMomentumAdvectionOutflowBC";
880 InputParameters params = getFactory().getValidParams(bc_type);
881 params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
883 params.set<MooseFunctorName>(NS::porosity) = _flow_porosity_functor_name;
884 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
885 params.set<MooseFunctorName>(NS::density) = _density_name;
886
887 for (unsigned int i = 0; i < dimension(); ++i)
888 params.set<MooseFunctorName>(u_names[i]) = _velocity_names[i];
889
890 for (const auto d : make_range(dimension()))
891 {
892 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
893 params.set<MooseEnum>("momentum_component") = NS::directions[d];
894
895 getProblem().addFVBC(bc_type, _velocity_names[d] + "_" + outlet_bdy, params);
896 }
897 }
898 }
899
900 if (momentum_outlet_type == "fixed-pressure" ||
901 momentum_outlet_type == "fixed-pressure-zero-gradient")
902 {
903 const std::string bc_type = "INSFVOutletPressureBC";
904 InputParameters params = getFactory().getValidParams(bc_type);
905 params.set<NonlinearVariableName>("variable") = _pressure_name;
906 params.set<MooseFunctorName>("functor") = libmesh_map_find(_pressure_functors, outlet_bdy);
907 params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
908
909 getProblem().addFVBC(bc_type, _pressure_name + "_" + outlet_bdy, params);
910 }
911 else if (momentum_outlet_type == "zero-gradient")
912 {
913 const std::string bc_type = "INSFVMassAdvectionOutflowBC";
914 InputParameters params = getFactory().getValidParams(bc_type);
915 params.set<NonlinearVariableName>("variable") = _pressure_name;
916 params.set<MooseFunctorName>(NS::density) = _density_name;
917 params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
918
919 for (const auto d : make_range(dimension()))
920 params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
921
922 getProblem().addFVBC(bc_type, _pressure_name + "_" + outlet_bdy, params);
923 }
924 }
925}
926
927void
929{
930 const std::string u_names[3] = {"u", "v", "w"};
931
932 // Count the number of fixed velocity wall boundaries (moving walls)
933 unsigned int num_functor_walls = 0;
934 for (const auto & [boundary_name, momentum_wall_type] : _momentum_wall_types)
935 if (momentum_wall_type == "noslip")
936 num_functor_walls++;
937 if (_momentum_wall_functors.size() && num_functor_walls != _momentum_wall_functors.size())
938 paramError("momentum_wall_functors",
939 "If any wall functors are specified, the number of boundaries requiring a momentum "
940 "functor (" +
941 std::to_string(num_functor_walls) + ") and the number of functors specified (" +
942 std::to_string(_momentum_wall_functors.size()) + ") must match");
943 for (const auto & wall_functors : _momentum_wall_functors)
944 if (wall_functors.second.size() != dimension())
945 paramError("momentum_wall_functors",
946 "Number of wall functors (" + std::to_string(wall_functors.second.size()) +
947 ") must match dimension (" + std::to_string(dimension()) +
948 ").\nFunctors currently specified:" + Moose::stringify(wall_functors.second));
949
950 for (const auto & [boundary_name, wall_type] : _momentum_wall_types)
951 {
952 if (wall_type == "noslip")
953 {
954 const std::string bc_type = "INSFVNoSlipWallBC";
955 InputParameters params = getFactory().getValidParams(bc_type);
956 params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
957
958 for (const auto d : make_range(dimension()))
959 {
960 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
961 if (_momentum_wall_functors.count(boundary_name) == 0)
962 params.set<FunctionName>("function") = "0";
963 else
964 params.set<FunctionName>("function") = _momentum_wall_functors[boundary_name][d];
965
966 getProblem().addFVBC(bc_type, _velocity_names[d] + "_" + boundary_name, params);
967 }
968 }
969 else if (wall_type == "wallfunction")
970 {
971 const std::string bc_type = "INSFVWallFunctionBC";
972 InputParameters params = getFactory().getValidParams(bc_type);
973 params.set<MooseFunctorName>(NS::mu) = _dynamic_viscosity_name;
974 params.set<MooseFunctorName>(NS::density) = _density_name;
975 params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
976 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
977
978 for (const auto d : make_range(dimension()))
979 params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
980
981 for (const auto d : make_range(dimension()))
982 {
983 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
984 params.set<MooseEnum>("momentum_component") = NS::directions[d];
985
986 getProblem().addFVBC(bc_type, _velocity_names[d] + "_" + boundary_name, params);
987 }
988 }
989 else if (wall_type == "slip")
990 {
991 const std::string bc_type = "INSFVNaturalFreeSlipBC";
992 InputParameters params = getFactory().getValidParams(bc_type);
993 params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
994 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
995
996 for (const auto d : make_range(dimension()))
997 {
998 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
999 params.set<MooseEnum>("momentum_component") = NS::directions[d];
1000
1001 getProblem().addFVBC(bc_type, _velocity_names[d] + "_" + boundary_name, params);
1002 }
1003 }
1004 else if (wall_type == "symmetry")
1005 {
1006 {
1007 std::string bc_type;
1009 bc_type = "PINSFVSymmetryVelocityBC";
1010 else
1011 bc_type = "INSFVSymmetryVelocityBC";
1012
1013 InputParameters params = getFactory().getValidParams(bc_type);
1014 params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
1015
1016 MooseFunctorName viscosity_name = _dynamic_viscosity_name;
1018 viscosity_name = NS::total_viscosity;
1019 params.set<MooseFunctorName>(NS::mu) = viscosity_name;
1020 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
1021
1022 for (const auto d : make_range(dimension()))
1023 params.set<MooseFunctorName>(u_names[d]) = _velocity_names[d];
1024
1025 for (const auto d : make_range(dimension()))
1026 {
1027 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
1028 params.set<MooseEnum>("momentum_component") = NS::directions[d];
1029
1030 getProblem().addFVBC(bc_type, _velocity_names[d] + "_" + boundary_name, params);
1031 }
1032 }
1033 {
1034 const std::string bc_type = "INSFVSymmetryPressureBC";
1035 InputParameters params = getFactory().getValidParams(bc_type);
1036 params.set<NonlinearVariableName>("variable") = _pressure_name;
1037 params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
1038
1039 getProblem().addFVBC(bc_type, _pressure_name + "_" + boundary_name, params);
1040 }
1041 }
1042 }
1043}
1044
1045void
1047{
1048 if (_hydraulic_separators.size())
1049 {
1050 std::string bc_type = "INSFVVelocityHydraulicSeparatorBC";
1051 InputParameters params = getFactory().getValidParams(bc_type);
1052 params.set<std::vector<BoundaryName>>("boundary") = _hydraulic_separators;
1053 params.set<UserObjectName>("rhie_chow_user_object") = rhieChowUOName();
1054
1055 for (const auto d : make_range(dimension()))
1056 {
1057 params.set<NonlinearVariableName>("variable") = _velocity_names[d];
1058 params.set<MooseEnum>("momentum_component") = NS::directions[d];
1059 getProblem().addFVBC(bc_type, prefix() + _velocity_names[d] + "_separators", params);
1060 }
1061
1062 bc_type = "INSFVScalarFieldSeparatorBC";
1063 params = getFactory().getValidParams(bc_type);
1064 params.set<std::vector<BoundaryName>>("boundary") = _hydraulic_separators;
1065 params.set<NonlinearVariableName>("variable") = _pressure_name;
1066 getProblem().addFVBC(bc_type, prefix() + _pressure_name + "_separators", params);
1067 }
1068}
1069
1070void
1072{
1073 // Rhie Chow user object for interpolation velocities
1075}
1076
1077void
1079{
1081 return;
1082
1083 // Pressure pin
1084 if (getParam<bool>("pin_pressure"))
1085 {
1086 const auto pin_type = getParam<MooseEnum>("pinned_pressure_type");
1087 std::string object_type = "NSPressurePin";
1088
1089 // No need for the user object
1090 if (pin_type == "point-value" || pin_type == "average")
1091 return;
1092
1093 // Create the average value postprocessor if needed
1094 if (pin_type == "average-uo")
1095 {
1096 // Volume average by default, but we could do inlet or outlet for example
1097 InputParameters params = getFactory().getValidParams("ElementAverageValue");
1098 params.set<std::vector<VariableName>>("variable") = {_pressure_name};
1099 assignBlocks(params, _blocks);
1100 params.set<std::vector<OutputName>>("outputs") = {"none"};
1101 getProblem().addPostprocessor("ElementAverageValue", "ns_pressure_average", params);
1102 }
1103
1104 InputParameters params = getFactory().getValidParams(object_type);
1105 if (pin_type == "point-value" || pin_type == "point-value-uo")
1106 params.set<MooseEnum>("pin_type") = "point-value";
1107 else
1108 params.set<MooseEnum>("pin_type") = "average";
1109
1110 params.set<PostprocessorName>("phi0") = getParam<PostprocessorName>("pinned_pressure_value");
1111 params.set<NonlinearVariableName>("variable") = _pressure_name;
1112 if (pin_type == "point-value" || pin_type == "point-value-uo")
1113 params.set<Point>("point") = getParam<Point>("pinned_pressure_point");
1114 else if (pin_type == "average-uo")
1115 params.set<PostprocessorName>("pressure_average") = "ns_pressure_average";
1116
1117 getProblem().addUserObject(object_type, prefix() + "ins_mass_pressure_pin", params);
1118 }
1119}
1120
1121bool
1123{
1124 for (const auto block_i : index_range(_friction_types))
1125 for (const auto type_i : index_range(_friction_types[block_i]))
1126 if (MooseUtils::toUpper(_friction_types[block_i][type_i]) == "FORCHHEIMER")
1127 return true;
1128 return false;
1129}
1130
1131unsigned short
1133{
1135 if (_porous_medium_treatment && isParamValid("porosity_smoothing_layers"))
1136 ghost_layers = std::max(getParam<unsigned short>("porosity_smoothing_layers"), ghost_layers);
1138 getParam<MooseEnum>("porosity_interface_pressure_treatment") != "automatic") ||
1139 getParam<MooseEnum>("momentum_face_interpolation") == "skewness-corrected" ||
1140 getParam<MooseEnum>("pressure_face_interpolation") == "skewness-corrected")
1141 ghost_layers = std::max(ghost_layers, (unsigned short)3);
1142 return ghost_layers;
1143}
1144
1145void
1147{
1148 mooseAssert(dimension(), "0-dimension not supported");
1149
1150 // First make sure that we only add this object once
1151 // Potential cases:
1152 // - there is a flow physics, and an advection one (UO should be added by one)
1153 // - there is only an advection physics (UO should be created)
1154 // - there are two advection physics on different blocks with set velocities (first one picks)
1155 // Counting RC UOs defined on the same blocks seems to be the most fool proof option
1156 std::vector<UserObject *> objs;
1157 getProblem()
1158 .theWarehouse()
1159 .query()
1160 .condition<AttribSystem>("UserObject")
1161 .condition<AttribThread>(0)
1162 .queryInto(objs);
1163 bool have_matching_rc_uo = false;
1164 for (const auto & obj : objs)
1165 if (const auto * const rc_obj = dynamic_cast<INSFVRhieChowInterpolator *>(obj); rc_obj)
1166 // Latter check is for whether one of the RC user object is defined everywhere
1167 if (rc_obj->blocks() == _blocks || (rc_obj->blocks().size() == 0 || _blocks.size() == 0))
1168 {
1169 have_matching_rc_uo = true;
1170 _rc_uo_name = rc_obj->name();
1171 break;
1172 }
1173
1174 if (have_matching_rc_uo)
1175 return;
1176
1177 _rc_uo_name =
1178 _porous_medium_treatment ? +"pins_rhie_chow_interpolator" : "ins_rhie_chow_interpolator";
1179
1180 const std::string u_names[3] = {"u", "v", "w"};
1181 const auto object_type =
1182 _porous_medium_treatment ? "PINSFVRhieChowInterpolator" : "INSFVRhieChowInterpolator";
1183
1184 auto params = getFactory().getValidParams(object_type);
1185 assignBlocks(params, _blocks);
1186 for (unsigned int d = 0; d < dimension(); ++d)
1187 params.set<VariableName>(u_names[d]) = _velocity_names[d];
1188
1189 params.set<VariableName>("pressure") = _pressure_name;
1190
1192 {
1193 params.set<MooseFunctorName>(NS::porosity) = _porosity_name;
1194 unsigned short smoothing_layers = isParamValid("porosity_smoothing_layers")
1195 ? getParam<unsigned short>("porosity_smoothing_layers")
1196 : 0;
1197 params.set<unsigned short>("smoothing_layers") = smoothing_layers;
1198 }
1199
1201 {
1203 params.set<MooseFunctorName>("a_u") = "ax";
1204 params.set<MooseFunctorName>("a_v") = "ay";
1205 params.set<MooseFunctorName>("a_w") = "az";
1206 }
1207
1208 params.applySpecificParameters(parameters(), INSFVRhieChowInterpolator::listOfCommonParams());
1209 addUserObject(object_type, _rc_uo_name, params);
1210}
1211
1212std::vector<UserObjectName>
1217
1218void
1220{
1221 if (!getProblem().hasFunctor("ax", /*thread_id=*/0))
1222 mooseError("Rhie Chow coefficient ax must be provided for advection by auxiliary velocities");
1223 if (dimension() >= 2 && !getProblem().hasFunctor("ay", /*thread_id=*/0))
1224 mooseError("Rhie Chow coefficient ay must be provided for advection by auxiliary velocities");
1225 if (dimension() == 3 && !getProblem().hasFunctor("az", /*thread_id=*/0))
1226 mooseError("Rhie Chow coefficient az must be provided for advection by auxiliary velocities");
1227}
1228
1229MooseFunctorName
1231{
1232 // Check all blocks. If more than one block, they would need to be consolidated #include in
1233 // a single functor material. We won't implement this for now
1234 if (_friction_types.empty())
1235 return "";
1236 else if (_friction_types.size() == 1)
1237 {
1238 for (const auto & type_i : index_range(_friction_types[0]))
1239 {
1240 const auto upper_name = MooseUtils::toUpper(_friction_types[0][type_i]);
1241 if (upper_name == "DARCY")
1242 return _friction_coeffs[0][type_i];
1243 }
1244 // No linear type found
1245 return "";
1246 }
1247 else if (_friction_types.size() > 1)
1248 {
1249 bool linear_friction_factor_found = false;
1250 MooseFunctorName linear_friction_factor;
1251 for (const auto block_i : index_range(_friction_types))
1252 for (const auto type_i : index_range(_friction_types[block_i]))
1253 {
1254 const auto upper_name = MooseUtils::toUpper(_friction_types[block_i][type_i]);
1255 if (upper_name == "DARCY" && !linear_friction_factor_found)
1256 {
1257 linear_friction_factor_found = true;
1258 linear_friction_factor = _friction_types[block_i][type_i];
1259 }
1260 else if (upper_name == "DARCY" && !linear_friction_factor_found)
1261 if (linear_friction_factor != _friction_types[block_i][type_i])
1262 mooseError("Multiple linear friction factor with different names have been specified. "
1263 "This is not currently supported as a single name should be retrievable. "
1264 "Use a PiecewiseByBlockFunctorMaterial to consolidate them.");
1265 }
1266 if (linear_friction_factor_found)
1267 return linear_friction_factor;
1268 else
1269 return "";
1270 }
1271 mooseError("Should not get here");
1272}
std::vector< VariableName > CoupledName
registerWCNSFVFlowPhysicsBaseTasks("NavierStokesApp", WCNSFVFlowPhysics)
registerMooseAction("NavierStokesApp", WCNSFVFlowPhysics, "add_fv_kernel")
std::shared_ptr< FEProblemBase > & _problem
virtual std::vector< std::shared_ptr< UserObject > > addUserObject(const std::string &user_object_name, const std::string &name, InputParameters &parameters)
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
virtual void addFVBC(const std::string &fv_bc_name, const std::string &name, InputParameters &parameters)
virtual void addPostprocessor(const std::string &pp_name, const std::string &name, InputParameters &parameters)
TheWarehouse & theWarehouse() const
virtual void addFVKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
InputParameters getValidParams(const std::string &name) const
static InputParameters validParams()
static std::vector< std::string > listOfCommonParams()
This user-object gathers 'a' (on-diagonal velocity coefficients) data.
static std::vector< std::string > listOfCommonParams()
void errorDependentParameter(const std::string &param1, const std::string &value_not_set, const std::vector< std::string > &dependent_params) const
void checkSecondParamSetOnlyIfFirstOneTrue(const std::string &param1, const std::string &param2) const
void applySpecificParameters(const InputParameters &common, const std::vector< std::string > &include, bool allow_private=false)
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
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
const std::string & type() const
void paramWarning(const std::string &param, Args... args) const
void paramError(const std::string &param, Args... args) const
bool isParamSetByUser(const std::string &name) const
void mooseError(Args &&... args) const
const T & getParam(const std::string &name) const
bool isParamValid(const std::string &name) const
static InputParameters validParams()
Definition NSFVBase.C:378
bool _define_variables
Whether to define variables if they do not exist.
virtual FEProblemBase & getProblem()
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
void addSharedSolverVariable(const std::string &var_type, const VariableName &var_name, InputParameters params)
bool shouldCreateVariable(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool error_if_aux)
bool isTransient() const
std::vector< SubdomainName > _blocks
Query query()
Base class for Physics which create the Navier Stokes flow equations.
std::map< BoundaryName, MooseEnum > _momentum_outlet_types
Momentum outlet boundary types.
const MooseEnum _velocity_interpolation
The velocity face interpolation method for advecting other quantities.
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< PostprocessorName > _flux_inlet_pps
Postprocessors describing the momentum inlet for each boundary. Indexing based on the number of flux ...
const MooseEnum _momentum_advection_interpolation
The momentum face interpolation method for being advected.
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.
MooseFunctorName _flow_porosity_functor_name
Name of the porosity functor for the flow equations (if smoothed)
void addAxisymmetricViscousSource()
Adds the cylindrical source kernel for the radial momentum equation when requested and valid.
const NonlinearVariableName _pressure_name
Pressure name.
const bool _has_flow_equations
Boolean to keep track of whether the flow equations should be created.
bool includeIsotropicStress() const
Whether to include the isotropic viscous stress contribution.
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.
const UserObjectName & rhieChowUOName() const
Return the name of the Rhie Chow user object.
std::vector< Point > _flux_inlet_directions
Direction of each flux inlet. Indexing based on the number of flux boundaries.
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.
bool hasTurbulencePhysics() const
Whether a turbulence Physics has been coupled in, to know which viscosity to pick on symmetry boundar...
const MooseFunctorName _density_name
Name of the density material property.
const MooseFunctorName _porosity_name
Name of the porosity functor.
unsigned short getNumberAlgebraicGhostingLayersNeeded() const override
Return the number of algebraic ghosting layers needed.
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 mass and momentum equations.
unsigned short getNumberAlgebraicGhostingLayersNeeded() const override
Return the number of algebraic ghosting layers needed.
void addAxisymmetricViscousSourceKernel(const std::vector< SubdomainName > &rz_blocks, unsigned int radial_index) override
Derived classes must override this hook to add the actual object that implements the axisymmetric vis...
void addMomentumBoussinesqKernels() override
void addMassKernels()
Function adding kernels for the incompressible continuity equation.
void addMomentumPressureKernels() override
virtual void addUserObjects() override
void addRhieChowUserObjects() override
Function which adds the RhieChow interpolator user objects for weakly and incompressible formulations...
void addMassTimeKernels()
Function adding kernels for the time derivative term of the weakly compressible continuity equation.
void addWallsBC() override
void addMomentumTimeKernels() override
Functions adding kernels for the incompressible momentum equation If the material properties are not ...
void addMomentumGravityKernels() override
void addSeparatorBC() override
virtual void addSolverVariables() override
void checkRhieChowFunctorsDefined() const
Checks that sufficient Rhie Chow coefficients have been defined for the given dimension,...
void addMomentumViscousDissipationKernels()
void addOutletBC() override
virtual std::vector< UserObjectName > getSuppliedUserObjects() const override
virtual void addCorrectors() override
static InputParameters validParams()
void addMomentumFrictionKernels() override
UserObjectName _rc_uo_name
Name of the user object in charge of computing the Rhie Chow coefficients.
WCNSFVFlowPhysics(const InputParameters &parameters)
void addInletBC() override
Functions adding boundary conditions for the incompressible simulation.
void addPressurePinKernel()
Function adding the pressure constraint.
virtual void addFVKernels() override
virtual MooseFunctorName getLinearFrictionCoefName() const override
Get the name of the linear friction coefficient. Returns an empty string if no friction.
bool hasForchheimerFriction() const override
Return whether a Forchheimer friction model is in use.
std::string toUpper(std::string name)
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
static const std::string mu
Definition NS.h:127
const std::string velocity_vector[3]
Definition NS.h:50
static const std::string smoothed_porosity
Definition NS.h:109
static const std::string porosity
Definition NS.h:108
static const std::string directions[3]
Definition NS.h:23
static const std::string speed
Definition NS.h:148
std::string time_deriv(const std::string &var)
Definition NS.h:98
static const std::string total_viscosity
Definition NS.h:79