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