https://mooseframework.inl.gov
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"
13 #include "INSFVMomentumAdvection.h"
14 #include "RhieChowMassFlux.h"
15 #include "INSFVTimeKernel.h"
16 #include "MapConversionUtils.h"
17 #include "NSFVUtils.h"
18 #include "NS.h"
19 
21 registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_interpolation_method_physics");
22 registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_linear_fv_kernel");
23 registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_linear_fv_bc");
24 registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_functor_material");
25 
28 {
30  params.addClassDescription(
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 
100 void
102 {
103  if (!_has_flow_equations || isParamValid("momentum_advection_interpolation_method_name"))
104  return;
105 
106  addFVAdvectedInterpolationMethod(getParam<MooseEnum>("momentum_advection_interpolation"));
107 }
108 
109 void
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
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 
129 void
131 {
132  if (!_has_flow_equations)
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 
189 void
191 {
192  if (!_has_flow_equations)
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 
220 void
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 
249 void
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 
267 void
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);
282  if (!_turbulence_physics)
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 
305 void
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 
323 void
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 + "_" +
367  NS::directions[d],
368  params);
369  }
370  }
371 }
372 
373 void
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 
397 void
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 
424 void
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 
507 void
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 
558 void
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 
641 void
643 {
644  mooseAssert(!_porous_medium_treatment, "Not implemented");
645  // Rhie Chow user object for interpolation velocities
647 }
648 
649 void
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 
701 std::vector<UserObjectName>
703 {
704  return {rhieChowUOName()};
705 }
706 
707 void
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 
733 unsigned short
735 {
736  return 1;
737 }
virtual void addFVKernels() override
std::string prefix() const
Creates all the objects needed to solve the Navier-Stokes equations with the SIMPLE algorithm using t...
virtual void addFVInterpolationMethods() override
void addUserObject(const std::string &uo_type, const std::string &uo_name, InputParameters &params)
unsigned short getNumberAlgebraicGhostingLayersNeeded() const override
Return the number of algebraic ghosting layers needed.
void renameParam(const std::string &old_name, const std::string &new_name, const std::string &new_docstring)
const bool _has_flow_equations
Boolean to keep track of whether the flow equations should be created.
void assignBlocks(InputParameters &params, const std::vector< SubdomainName > &blocks) const
bool shouldCreateVariable(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool error_if_aux)
virtual void addInletBC() override
Functions adding boundary conditions for the flow simulation.
User object responsible for determining the face fluxes using the Rhie-Chow interpolation in a segreg...
Factory & getFactory()
std::vector< std::vector< std::string > > _friction_types
The friction correlation types used for each block.
std::map< BoundaryName, MooseEnum > _momentum_inlet_types
Momentum inlet boundary types.
void paramError(const std::string &param, Args... args) const
virtual void addMomentumPressureKernels() override
void addRequiredPhysicsTask(const std::string &task)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
virtual void initializePhysicsAdditional() override
virtual std::vector< UserObjectName > getSuppliedUserObjects() const override
const MooseFunctorName _density_name
Name of the density material property.
MooseEnum fvFaceInterpolationMethods()
Enum of the interpolation methods supported by FVInterpolationMethod objects.
Definition: NSFVUtils.C:85
const MooseFunctorName _density_gravity_name
Name of the density material property used for gravity and Boussinesq terms.
void addFVAdvectedInterpolationMethod(const MooseEnum &interpolation_method)
Add the FVInterpolationMethod object for an advected interpolation method if absent.
virtual void addMaterial(const std::string &material_name, const std::string &name, InputParameters &parameters)
virtual void addFunctorMaterials() override
const InputParameters & parameters() const
T & set(const std::string &name, bool quiet_mode=false)
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 ...
static const std::string density
Definition: NS.h:34
InputParameters getValidParams(const std::string &name) const
void reportPotentiallyMissedParameters(const std::vector< std::string > &param_names, const std::string &object_type, const std::string &object_name="") const
std::map< BoundaryName, std::vector< MooseFunctorName > > _momentum_inlet_functors
Functors describing the momentum inlet for each boundary.
virtual void initializePhysicsAdditional() override
registerMooseAction("NavierStokesApp", WCNSLinearFVFlowPhysics, "add_interpolation_method_physics")
std::map< BoundaryName, std::vector< MooseFunctorName > > _momentum_wall_functors
Functors describing the momentum for each wall boundary.
const NonlinearVariableName _pressure_name
Pressure name.
void addPressureCorrectionKernels()
Function adding kernels for the incompressible pressure correction equation.
bool shouldCreateTimeDerivative(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool error_if_already_defined) const
static InputParameters validParams()
const bool _porous_medium_treatment
Whether to use the porous medium treatment.
std::vector< SubdomainName > _blocks
const std::vector< BoundaryName > _wall_boundaries
Boundaries which define a wall (slip/noslip/etc.)
unsigned int dimension() const
bool includeSymmetrizedViscousStress() const
Whether to include the symmetrized contribution in the viscous stress.
static const std::string directions[3]
Definition: NS.h:23
void suppressParameter(const std::string &name)
std::string toUpper(std::string name)
virtual void addWallsBC() override
virtual FEProblemBase & getProblem()
const SolverSystemName & getSolverSystem(unsigned int variable_index) const
static const std::string T_fluid
Definition: NS.h:110
std::vector< std::vector< SubdomainName > > _friction_blocks
Subdomains where we want to have volumetric friction.
TheWarehouse & theWarehouse() const
virtual void addMomentumGravityKernels() override
std::map< BoundaryName, MooseEnum > _momentum_outlet_types
Momentum outlet boundary types.
static const std::string mu
Definition: NS.h:127
const std::vector< std::string > _velocity_names
Velocity names.
static InputParameters validParams()
Base class for Physics which create the Navier Stokes flow equations.
WCNSLinearFVFlowPhysics(const InputParameters &parameters)
virtual void addUserObjects() override
void needSolutionState(unsigned int oldest_needed, Moose::SolutionIterationType iteration_type)
const MooseFunctorName _dynamic_viscosity_name
Name of the dynamic viscosity material property.
std::string stringify(const T &t)
static const std::string mu_eff
Definition: NS.h:133
const bool _solve_for_dynamic_pressure
Whether we are solving for the total or dynamic pressure.
void transferParam(const InputParameters &source_param, const std::string &name, const std::string &new_name="", const std::string &new_description="")
const bool _non_orthogonal_correction
Whether to use the correction term for non-orthogonality.
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
const MooseEnum _compressibility
Compressibility type, can be compressible, incompressible or weakly-compressible. ...
bool _define_variables
Whether to define variables if they do not exist.
virtual void addLinearFVKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
registerWCNSFVFlowPhysicsBaseTasks("NavierStokesApp", WCNSLinearFVFlowPhysics)
std::map< BoundaryName, MooseEnum > _momentum_wall_types
Momentum wall boundary types.
const NonlinearVariableName _fluid_temperature_name
Fluid temperature name.
MooseEnum fvAdvectedInterpolationMethods()
Enum of the advected interpolation methods supported by FVInterpolationMethod objects.
Definition: NSFVUtils.C:61
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void addMomentumFrictionKernels() override
virtual void addMomentumBoussinesqKernels() override
std::map< BoundaryName, MooseFunctorName > _pressure_functors
Functors describing the outlet pressure on each boundary.
virtual void addLinearFVBC(const std::string &fv_bc_name, const std::string &name, InputParameters &parameters)
Query query()
const UserObjectName & rhieChowUOName() const
Return the name of the Rhie Chow user object.
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
const std::vector< BoundaryName > _hydraulic_separators
Hydraulic separator boundaries.
static InputParameters validParams()
void addClassDescription(const std::string &doc_string)
bool isParamValid(const std::string &name) const
virtual void addOutletBC() override
bool parsesToReal(const std::string &input, Real *parsed_real)
bool isParamSetByUser(const std::string &name) const
void saveSolverVariableName(const VariableName &var_name)
virtual void addSolverVariables() override
std::vector< SolverSystemName > _system_names
bool isTransient() const
std::vector< std::vector< std::string > > _friction_coeffs
The coefficients used for each item if friction type.
const WCNSFVTurbulencePhysicsBase * _turbulence_physics
Can be set to a coupled turbulence physics.
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)