https://mooseframework.inl.gov
WCNSLinearFVScalarTransportPhysics.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 
11 #include "WCNSFVFlowPhysicsBase.h"
12 #include "NSFVUtils.h"
13 #include "NS.h"
14 
17 registerMooseAction("NavierStokesApp",
19  "add_interpolation_method_physics");
20 
23 {
25  params.addClassDescription("Define the Navier Stokes weakly-compressible scalar field transport "
26  "equation(s) using the linear finite volume discretization");
27  params.set<MooseEnum>("passive_scalar_advection_interpolation") =
29  params.addParam<InterpolationMethodName>(
30  "passive_scalar_advection_interpolation_method_name",
31  "Name of an externally defined FVInterpolationMethod to use for passive scalar advection. "
32  "When provided, this overrides 'passive_scalar_advection_interpolation'.");
33  params.addParam<bool>("use_nonorthogonal_correction",
34  true,
35  "If the nonorthogonal correction should be used when computing the normal "
36  "gradient, notably in the diffusion term.");
37 
38  // Not supported
39  params.suppressParameter<MooseEnum>("preconditioning");
40 
41  params.addParamNamesToGroup("passive_scalar_advection_interpolation_method_name",
42  "Numerical scheme");
43 
44  return params;
45 }
46 
48  const InputParameters & parameters)
50 {
51  addRequiredPhysicsTask("add_interpolation_method_physics");
52 
54  _flow_equations_physics->paramError("porous_medium_treatment",
55  "Porous media scalar advection is currently unimplemented");
56 }
57 
58 void
60 {
61  if (!_has_scalar_equation || isParamValid("passive_scalar_advection_interpolation_method_name"))
62  return;
63 
64  addFVAdvectedInterpolationMethod(getParam<MooseEnum>("passive_scalar_advection_interpolation"));
65 }
66 
67 void
69 {
70  // For compatibility with Modules/NavierStokesFV syntax
72  return;
73 
74  auto params = getFactory().getValidParams("MooseLinearVariableFVReal");
75  assignBlocks(params, _blocks);
76 
77  for (const auto name_i : index_range(_passive_scalar_names))
78  {
79  // Dont add if the user already defined the variable
80  if (!shouldCreateVariable(_passive_scalar_names[name_i], _blocks, /*error if aux*/ true))
81  {
82  reportPotentiallyMissedParameters({"system_names", "passive_scalar_scaling"},
83  "MooseLinearVariableFVReal");
84  continue;
85  }
86 
87  params.set<SolverSystemName>("solver_sys") = getSolverSystem(name_i);
88  if (isParamValid("passive_scalar_scaling"))
89  params.set<std::vector<Real>>("scaling") = {
90  getParam<std::vector<Real>>("passive_scalar_scaling")[name_i]};
91 
92  getProblem().addVariable("MooseLinearVariableFVReal", _passive_scalar_names[name_i], params);
93  }
94 }
95 
96 void
98 {
99  std::string kernel_type = "LinearFVTimeDerivative";
100  InputParameters params = getFactory().getValidParams(kernel_type);
101  assignBlocks(params, _blocks);
102 
103  for (const auto & vname : _passive_scalar_names)
104  {
105  params.set<LinearVariableName>("variable") = vname;
106  if (shouldCreateTimeDerivative(vname, _blocks, /*error if already defined */ false))
107  getProblem().addLinearFVKernel(kernel_type, prefix() + "ins_" + vname + "_time", params);
108  }
109 }
110 
111 void
113 {
114  const auto method_name =
115  isParamValid("passive_scalar_advection_interpolation_method_name")
116  ? getParam<InterpolationMethodName>("passive_scalar_advection_interpolation_method_name")
117  : InterpolationMethodName(
118  std::string(getParam<MooseEnum>("passive_scalar_advection_interpolation")));
119 
120  const std::string kernel_type = "LinearFVScalarAdvection";
121  InputParameters params = getFactory().getValidParams(kernel_type);
122 
123  assignBlocks(params, _blocks);
124  params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName();
125  params.set<InterpolationMethodName>("advected_interp_method_name") = method_name;
126  setSlipVelocityParams(params);
127 
128  for (const auto & vname : _passive_scalar_names)
129  {
130  params.set<LinearVariableName>("variable") = vname;
131  getProblem().addLinearFVKernel(kernel_type, prefix() + "ins_" + vname + "_advection", params);
132  }
133 }
134 
135 void
137 {
138  // Direct specification of diffusion term
139  const auto passive_scalar_diffusivities =
140  getParam<std::vector<MooseFunctorName>>("passive_scalar_diffusivity");
141 
142  if (passive_scalar_diffusivities.size())
143  {
144  const std::string kernel_type = "LinearFVDiffusion";
145  InputParameters params = getFactory().getValidParams(kernel_type);
146  assignBlocks(params, _blocks);
147  params.set<bool>("use_nonorthogonal_correction") =
148  getParam<bool>("use_nonorthogonal_correction");
149  for (const auto name_i : index_range(_passive_scalar_names))
150  {
151  params.set<LinearVariableName>("variable") = _passive_scalar_names[name_i];
152  params.set<MooseFunctorName>("diffusion_coeff") =
153  passive_scalar_diffusivities[name_i] + (_has_turbulence_model ? "_plus_mut/Sc_t" : "");
155  kernel_type, prefix() + "ins_" + _passive_scalar_names[name_i] + "_diffusion", params);
156  }
157  }
158 }
159 
160 void
162 {
163  const std::string kernel_type = "LinearFVSource";
164  InputParameters params = getFactory().getValidParams(kernel_type);
165  assignBlocks(params, _blocks);
166 
167  for (const auto scalar_i : index_range(_passive_scalar_names))
168  {
169  params.set<LinearVariableName>("variable") = _passive_scalar_names[scalar_i];
170 
171  if (_passive_scalar_sources.size())
172  {
173  // Added for backward compatibility with former Modules/NavierStokesFV syntax
174  params.set<MooseFunctorName>("source_density") = _passive_scalar_sources[scalar_i];
176  kernel_type, prefix() + "ins_" + _passive_scalar_names[scalar_i] + "_source", params);
177  }
178 
180  for (const auto i : index_range(_passive_scalar_coupled_sources[scalar_i]))
181  {
182  params.set<MooseFunctorName>("source_density") =
183  _passive_scalar_coupled_sources[scalar_i][i];
184  if (_passive_scalar_sources_coef.size())
185  params.set<Real>("scaling_factor") = _passive_scalar_sources_coef[scalar_i][i];
186 
187  getProblem().addLinearFVKernel(kernel_type,
188  prefix() + "ins_" + _passive_scalar_names[scalar_i] +
189  "_coupled_source_" + std::to_string(i),
190  params);
191  }
192  }
193 }
194 
195 void
197 {
198  const auto & inlet_boundaries = _flow_equations_physics->getInletBoundaries();
199  if (inlet_boundaries.empty())
200  return;
201 
202  // Boundary checks
203  // TODO: once we have vectors of MooseEnum, we could use the same templated check for types and
204  // functors
205  if (inlet_boundaries.size() * _passive_scalar_names.size() != _passive_scalar_inlet_types.size())
206  paramError(
207  "passive_scalar_inlet_types",
208  "The number of scalar inlet types (" + std::to_string(_passive_scalar_inlet_types.size()) +
209  ") is not equal to the number of inlet boundaries (" +
210  std::to_string(inlet_boundaries.size()) + ") times the number of passive scalars (" +
211  std::to_string(_passive_scalar_names.size()) + ")");
213  paramError("passive_scalar_inlet_functors",
214  "The number of groups of inlet functors (" +
215  std::to_string(_passive_scalar_inlet_functors.size()) +
216  ") is not equal to the number of passive scalars (" +
217  std::to_string(_passive_scalar_names.size()) + ")");
218 
219  for (const auto name_i : index_range(_passive_scalar_names))
220  {
221  if (inlet_boundaries.size() != _passive_scalar_inlet_functors[name_i].size())
222  paramError("passive_scalar_inlet_functors",
223  "The number of inlet boundary functors for scalar '" +
224  _passive_scalar_names[name_i] +
225  "' does not match the number of inlet boundaries (" +
226  std::to_string(_passive_scalar_inlet_functors[name_i].size()) + ")");
227 
228  unsigned int num_inlets = inlet_boundaries.size();
229  for (unsigned int bc_ind = 0; bc_ind < num_inlets; ++bc_ind)
230  {
231  if (_passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "fixed-value")
232  {
233  const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
234  InputParameters params = getFactory().getValidParams(bc_type);
235  params.set<LinearVariableName>("variable") = _passive_scalar_names[name_i];
236  params.set<MooseFunctorName>("functor") = _passive_scalar_inlet_functors[name_i][bc_ind];
237  params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]};
238 
240  bc_type, _passive_scalar_names[name_i] + "_" + inlet_boundaries[bc_ind], params);
241  }
242  else if (_passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "flux-mass" ||
243  _passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "flux-velocity")
244  {
245  mooseError("Flux boundary conditions not supported at this time using the linear finite "
246  "volume discretization");
247  }
248  }
249  }
250 }
251 
252 unsigned short
254 {
255  return 1;
256 }
257 
258 void
260 {
261  const auto & outlet_boundaries = _flow_equations_physics->getOutletBoundaries();
262  if (outlet_boundaries.empty())
263  return;
264 
265  for (const auto & outlet_bdy : outlet_boundaries)
266  {
267  const std::string bc_type = "LinearFVAdvectionDiffusionOutflowBC";
268  InputParameters params = getFactory().getValidParams(bc_type);
269  params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
270  params.set<bool>("use_two_term_expansion") =
271  getParam<bool>("passive_scalar_two_term_bc_expansion");
272 
273  for (const auto name_i : index_range(_passive_scalar_names))
274  {
275  params.set<LinearVariableName>("variable") = _passive_scalar_names[name_i];
276  getProblem().addLinearFVBC(bc_type, _passive_scalar_names[name_i] + "_" + outlet_bdy, params);
277  }
278  }
279 }
std::string prefix() const
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)
Factory & getFactory()
void paramError(const std::string &param, Args... args) const
const std::vector< BoundaryName > & getOutletBoundaries() const
Get the outlet boundaries.
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)
const std::vector< BoundaryName > & getInletBoundaries() const
Get the inlet boundaries.
void addFVAdvectedInterpolationMethod(const MooseEnum &interpolation_method)
Add the FVInterpolationMethod object for an advected interpolation method if absent.
T & set(const std::string &name, bool quiet_mode=false)
registerNavierStokesPhysicsBaseTasks("NavierStokesApp", WCNSLinearFVScalarTransportPhysics)
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
unsigned int size() const
Creates all the objects needed to solve the Navier Stokes scalar transport equations using the linear...
bool _has_turbulence_model
Because of the Modules/navierStokesFV syntax, a turbulence physics often exists without a model we sa...
std::vector< NonlinearVariableName > _passive_scalar_names
Names of the passive scalar variables.
bool shouldCreateTimeDerivative(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool error_if_already_defined) const
std::vector< SubdomainName > _blocks
void suppressParameter(const std::string &name)
std::vector< std::vector< MooseFunctorName > > _passive_scalar_inlet_functors
Functors describing the inlet boundary values. See passive_scalar_inlet_types for what the functors a...
virtual FEProblemBase & getProblem()
virtual void addScalarInletBC() override
Functions adding boundary conditions for the incompressible simulation.
const SolverSystemName & getSolverSystem(unsigned int variable_index) const
std::vector< std::vector< Real > > _passive_scalar_sources_coef
Coefficients multiplying for the passive scalar sources. Inner indexing is scalar variable index...
virtual void addScalarTimeKernels() override
Functions adding kernels for the incompressible / weakly-compressible scalar transport equation If th...
const bool _porous_medium_treatment
Switch to show if porous medium treatment is requested or not.
std::vector< std::vector< MooseFunctorName > > _passive_scalar_coupled_sources
Functors for the passive scalar (coupled) sources. Inner indexing is scalar variable index...
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
virtual void setSlipVelocityParams(InputParameters &) const
virtual void addLinearFVKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
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 addLinearFVBC(const std::string &fv_bc_name, const std::string &name, InputParameters &parameters)
const UserObjectName & rhieChowUOName() const
Return the name of the Rhie Chow user object.
Creates all the objects needed to solve the Navier Stokes scalar transport equations.
void mooseError(Args &&... args) const
std::vector< MooseFunctorName > _passive_scalar_sources
Functors for the passive scalar sources. Indexing is scalar variable index.
void addClassDescription(const std::string &doc_string)
bool isParamValid(const std::string &name) const
WCNSLinearFVScalarTransportPhysics(const InputParameters &parameters)
virtual unsigned short getNumberAlgebraicGhostingLayersNeeded() const override
Return the number of ghosting layers needed.
MultiMooseEnum _passive_scalar_inlet_types
Passive scalar inlet boundary types.
const bool _has_scalar_equation
A boolean to help compatibility with the old Modules/NavierStokesFV syntax or to deliberately skip ad...
registerMooseAction("NavierStokesApp", WCNSLinearFVScalarTransportPhysics, "add_interpolation_method_physics")
const WCNSFVFlowPhysicsBase * _flow_equations_physics
Flow physics.
auto index_range(const T &sizable)
registerWCNSFVScalarTransportBaseTasks("NavierStokesApp", WCNSLinearFVScalarTransportPhysics)
virtual void addScalarSourceKernels() override
Equivalent of NSFVAction addScalarCoupledSourceKernels.
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)