Line data Source code
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 "WCNSFVFlowPhysicsBase.h"
11 : #include "WCNSLinearFVFlowPhysics.h"
12 : #include "WCNSFVTurbulencePhysics.h"
13 : #include "NSFVBase.h"
14 : #include "MapConversionUtils.h"
15 : #include "NS.h"
16 : #include "MooseMesh.h"
17 :
18 : InputParameters
19 1181 : WCNSFVFlowPhysicsBase::validParams()
20 : {
21 1181 : InputParameters params = NavierStokesPhysicsBase::validParams();
22 1181 : params.addClassDescription("Base class for Physics defining the Navier Stokes flow equations");
23 :
24 1181 : params += NSFVBase::commonMomentumEquationParams();
25 2362 : params.addParam<bool>("add_flow_equations",
26 2362 : true,
27 : "Whether to add the flow equations. This parameter is not necessary when "
28 : "using the Physics syntax");
29 :
30 : // We pull in parameters from various flow objects. This helps make sure the parameters are
31 : // spelled the same way and match the evolution of other objects.
32 : // If we remove these objects, or change their parameters, these parameters should be updated
33 : // Downstream actions must either implement all these options, or redefine the parameter with
34 : // a restricted MooseEnum, or place an error in the constructor for unsupported configurations
35 : // We mostly pull the boundary parameters from NSFV Action
36 :
37 1181 : params += NSFVBase::commonNavierStokesFlowParams();
38 2362 : params.addParam<bool>("include_deviatoric_stress",
39 2362 : false,
40 : "Whether to include the symmetrized viscous stress contribution "
41 : "(grad(u)+grad(u)^T).");
42 2362 : params.deprecateParam(
43 : "include_deviatoric_stress", "include_symmetrized_viscous_stress", "12/31/2025");
44 2362 : params.addParam<bool>("include_isotropic_viscous_stress",
45 2362 : false,
46 : "Whether to add the isotropic -(2/3) mu div(u) I contribution to the "
47 : "viscous stress (requires complete expansion of the velocity gradient).");
48 2362 : params.addParam<bool>("add_rz_viscous_source",
49 2362 : true,
50 : "When true, automatically adds INSFVMomentumViscousSourceRZ to the radial "
51 : "momentum equation on RZ blocks. Disable if this term should be omitted.");
52 :
53 : // Momentum boundary conditions are important for advection problems as well
54 1181 : params += NSFVBase::commonMomentumBoundaryTypesParams();
55 :
56 : // Convenient for sharing the executioner block with a non-Physics syntax
57 : // or for defining the RhieChow user object outside the Physics
58 2362 : params.addParam<UserObjectName>(
59 : "rhie_chow_uo_name",
60 : "Name of the Rhie Chow user object. Defaults to 'pins_rhie_chow_interpolator' for porous "
61 : "flow and 'ins_rhie_chow_interpolator' for non-porous.");
62 :
63 : // Specify the weakly compressible boundary flux information. They are used for specifying in flux
64 : // boundary conditions for advection physics in WCNSFV
65 1181 : params += NSFVBase::commonMomentumBoundaryFluxesParams();
66 2362 : params.addParam<std::vector<std::vector<MooseFunctorName>>>(
67 : "momentum_wall_functors",
68 : {},
69 : "Functors for each component of the velocity value on walls. This is only necessary for the "
70 : "fixed-velocity momentum wall types.");
71 :
72 : // Most downstream physics implementations are valid for porous media too
73 : // If yours is not, please remember to disable the 'porous_medium_treatment' parameter
74 1181 : params.transferParam<bool>(NSFVBase::validParams(), "porous_medium_treatment");
75 1181 : params.transferParam<MooseFunctorName>(NSFVBase::validParams(), "porosity");
76 :
77 : // Initialization parameters
78 1181 : params.transferParam<std::vector<FunctionName>>(NSFVBase::validParams(), "initial_velocity");
79 1181 : params.transferParam<FunctionName>(NSFVBase::validParams(), "initial_pressure");
80 :
81 : // Spatial discretization scheme
82 : // Specify the numerical schemes for interpolations of velocity and pressure
83 1181 : params.transferParam<MooseEnum>(NSFVBase::validParams(), "velocity_interpolation");
84 1181 : params.transferParam<MooseEnum>(NSFVBase::validParams(), "momentum_advection_interpolation");
85 1181 : params.transferParam<MooseEnum>(NSFVBase::validParams(), "momentum_face_interpolation");
86 1181 : params.transferParam<bool>(NSFVBase::validParams(), "momentum_two_term_bc_expansion");
87 1181 : params.transferParam<bool>(NSFVBase::validParams(), "pressure_two_term_bc_expansion");
88 2362 : MooseEnum coeff_interp_method("average harmonic", "harmonic");
89 2362 : params.addParam<MooseEnum>("mu_interp_method",
90 : coeff_interp_method,
91 : "Switch that can select face interpolation method for the viscosity.");
92 :
93 : // Fluid properties
94 1181 : params.addParam<UserObjectName>(NS::fluid, "Fluid properties userobject");
95 2362 : params.addParam<FunctionName>(
96 2362 : "mu_rampdown", 1, "A function describing a ramp down of viscosity over time");
97 2362 : params.addParamNamesToGroup(NS::fluid + " mu_rampdown", "Material properties");
98 :
99 : // Parameter groups
100 2362 : params.addParamNamesToGroup(
101 : "velocity_variable pressure_variable initial_pressure initial_velocity", "Variables");
102 2362 : params.addParamNamesToGroup("density dynamic_viscosity", "Material properties");
103 2362 : params.addParamNamesToGroup("inlet_boundaries momentum_inlet_types momentum_inlet_functors",
104 : "Inlet boundary conditions");
105 2362 : params.addParamNamesToGroup("outlet_boundaries momentum_outlet_types pressure_functors",
106 : "Outlet boundary conditions");
107 2362 : params.addParamNamesToGroup("wall_boundaries momentum_wall_types momentum_wall_functors",
108 : "Wall boundary conditions");
109 2362 : params.addParamNamesToGroup(
110 : "include_symmetrized_viscous_stress include_isotropic_viscous_stress velocity_interpolation "
111 : "momentum_advection_interpolation momentum_two_term_bc_expansion "
112 : "pressure_two_term_bc_expansion mu_interp_method momentum_face_interpolation",
113 : "Numerical scheme");
114 2362 : params.addParamNamesToGroup("thermal_expansion", "Gravity treatment");
115 :
116 1181 : return params;
117 1181 : }
118 :
119 1181 : WCNSFVFlowPhysicsBase::WCNSFVFlowPhysicsBase(const InputParameters & parameters)
120 : : NavierStokesPhysicsBase(parameters),
121 2362 : _has_flow_equations(getParam<bool>("add_flow_equations")),
122 2362 : _add_rz_viscous_source(getParam<bool>("add_rz_viscous_source")),
123 2362 : _compressibility(getParam<MooseEnum>("compressibility")),
124 2362 : _solve_for_dynamic_pressure(getParam<bool>("solve_for_dynamic_pressure")),
125 2362 : _porous_medium_treatment(getParam<bool>("porous_medium_treatment")),
126 2362 : _porosity_name(getParam<MooseFunctorName>("porosity")),
127 : _flow_porosity_functor_name(_porosity_name),
128 2575 : _velocity_names(
129 1181 : isParamValid("velocity_variable")
130 1181 : ? getParam<std::vector<std::string>>("velocity_variable")
131 968 : : (_porous_medium_treatment
132 968 : ? std::vector<std::string>(NS::superficial_velocity_vector,
133 : NS::superficial_velocity_vector + 3)
134 : : std::vector<std::string>(NS::velocity_vector, NS::velocity_vector + 3))),
135 2530 : _pressure_name(isParamValid("pressure_variable")
136 1517 : ? getParam<NonlinearVariableName>("pressure_variable")
137 : : NS::pressure),
138 2394 : _fluid_temperature_name(isParamValid("fluid_temperature_variable")
139 1245 : ? getParam<NonlinearVariableName>("fluid_temperature_variable")
140 : : NS::T_fluid),
141 1181 : _density_name(getParam<MooseFunctorName>("density")),
142 2362 : _density_gravity_name(isParamValid("density_for_gravity_terms")
143 1181 : ? getParam<MooseFunctorName>("density_for_gravity_terms")
144 3543 : : getParam<MooseFunctorName>("density")),
145 1181 : _dynamic_viscosity_name(getParam<MooseFunctorName>("dynamic_viscosity")),
146 2362 : _include_symmetrized_viscous_stress(getParam<bool>("include_symmetrized_viscous_stress")),
147 2362 : _include_isotropic_viscous_stress(getParam<bool>("include_isotropic_viscous_stress")),
148 2374 : _rc_uo_name(isParamValid("rhie_chow_uo_name")
149 1181 : ? getParam<UserObjectName>("rhie_chow_uo_name")
150 1169 : : (_porous_medium_treatment ? "pins_rhie_chow_interpolator"
151 : : "ins_rhie_chow_interpolator")),
152 2362 : _velocity_interpolation(getParam<MooseEnum>("velocity_interpolation")),
153 2362 : _momentum_advection_interpolation(getParam<MooseEnum>("momentum_advection_interpolation")),
154 2362 : _momentum_face_interpolation(getParam<MooseEnum>("momentum_face_interpolation")),
155 2362 : _friction_blocks(getParam<std::vector<std::vector<SubdomainName>>>("friction_blocks")),
156 2362 : _friction_types(getParam<std::vector<std::vector<std::string>>>("friction_types")),
157 2362 : _friction_coeffs(getParam<std::vector<std::vector<std::string>>>("friction_coeffs")),
158 2362 : _inlet_boundaries(getParam<std::vector<BoundaryName>>("inlet_boundaries")),
159 2362 : _outlet_boundaries(getParam<std::vector<BoundaryName>>("outlet_boundaries")),
160 2362 : _wall_boundaries(getParam<std::vector<BoundaryName>>("wall_boundaries")),
161 3543 : _hydraulic_separators(getParam<std::vector<BoundaryName>>("hydraulic_separator_sidesets")),
162 2362 : _flux_inlet_pps(getParam<std::vector<PostprocessorName>>("flux_inlet_pps")),
163 4724 : _flux_inlet_directions(getParam<std::vector<Point>>("flux_inlet_directions"))
164 : {
165 : // Inlet boundary parameter checking
166 2362 : checkSecondParamSetOnlyIfFirstOneSet("flux_inlet_pps", "flux_inlet_directions");
167 1181 : if (_flux_inlet_directions.size())
168 28 : checkVectorParamsSameLengthIfSet<PostprocessorName, Point>("flux_inlet_pps",
169 : "flux_inlet_directions");
170 :
171 : // Boussinesq parameters checks
172 2362 : checkSecondParamSetOnlyIfFirstOneTrue("boussinesq_approximation", "ref_temperature");
173 2362 : checkSecondParamSetOnlyIfFirstOneSet("gravity", "boussinesq_approximation");
174 :
175 : // Dynamic pressure parameter checks
176 1181 : if (_compressibility != "incompressible" && _solve_for_dynamic_pressure)
177 0 : paramError("compressibility",
178 : "Solving for dynamic pressure is only implemented for incompressible flow");
179 :
180 : // Boundary parameters checking
181 2360 : checkVectorParamAndMultiMooseEnumLength<BoundaryName>("inlet_boundaries", "momentum_inlet_types");
182 2356 : checkVectorParamAndMultiMooseEnumLength<BoundaryName>("outlet_boundaries",
183 : "momentum_outlet_types");
184 2352 : checkVectorParamAndMultiMooseEnumLength<BoundaryName>("wall_boundaries", "momentum_wall_types");
185 : checkVectorParamLengthSameAsCombinedOthers<BoundaryName,
186 : std::vector<MooseFunctorName>,
187 2348 : PostprocessorName>(
188 : "inlet_boundaries", "momentum_inlet_functors", "flux_inlet_pps");
189 1173 : checkVectorParamsNoOverlap<BoundaryName>(
190 : {"inlet_boundaries", "outlet_boundaries", "wall_boundaries"});
191 :
192 : // Porous media parameters
193 2346 : checkSecondParamSetOnlyIfFirstOneTrue("porous_medium_treatment", "porosity");
194 :
195 1173 : if (_define_variables && _porous_medium_treatment)
196 1774 : for (const auto & name : NS::velocity_vector)
197 : {
198 1331 : const auto & it = std::find(_velocity_names.begin(), _velocity_names.end(), name);
199 1331 : if (it != _velocity_names.end())
200 2 : paramError("velocity_variable",
201 2 : "For porous medium simulations, functor name " + *it +
202 : " is already reserved for the automatically-computed interstitial velocity. "
203 : "Please choose another name for your external velocity variable!");
204 : }
205 :
206 : // Friction parameter checks
207 1171 : if (_friction_blocks.size())
208 228 : checkVectorParamsSameLength<std::vector<SubdomainName>, std::vector<std::string>>(
209 : "friction_blocks", "friction_types");
210 2340 : checkTwoDVectorParamsSameLength<std::string, std::string>("friction_types", "friction_coeffs");
211 :
212 : // Create maps for boundary-restricted parameters
213 2338 : _momentum_inlet_types = Moose::createMapFromVectorAndMultiMooseEnum<BoundaryName>(
214 : _inlet_boundaries, getParam<MultiMooseEnum>("momentum_inlet_types"));
215 2338 : _momentum_outlet_types = Moose::createMapFromVectorAndMultiMooseEnum<BoundaryName>(
216 : _outlet_boundaries, getParam<MultiMooseEnum>("momentum_outlet_types"));
217 2338 : _momentum_wall_types = Moose::createMapFromVectorAndMultiMooseEnum<BoundaryName>(
218 : _wall_boundaries, getParam<MultiMooseEnum>("momentum_wall_types"));
219 2338 : if (isParamSetByUser("momentum_inlet_functors"))
220 : {
221 : // Not all inlet boundary types require the specification of an inlet functor
222 : std::vector<BoundaryName> inlet_boundaries_with_functors;
223 2418 : for (const auto & boundary : _inlet_boundaries)
224 1404 : if (libmesh_map_find(_momentum_inlet_types, boundary) == "fixed-velocity" ||
225 18 : libmesh_map_find(_momentum_inlet_types, boundary) == "fixed-pressure")
226 1386 : inlet_boundaries_with_functors.push_back(boundary);
227 : _momentum_inlet_functors =
228 2064 : Moose::createMapFromVectors<BoundaryName, std::vector<MooseFunctorName>>(
229 : inlet_boundaries_with_functors,
230 : getParam<std::vector<std::vector<MooseFunctorName>>>("momentum_inlet_functors"));
231 1032 : }
232 2338 : if (isParamSetByUser("pressure_functors"))
233 : {
234 : // Not all outlet boundary types require the specification of an inlet functor
235 : std::vector<BoundaryName> outlet_boundaries_with_functors;
236 2048 : for (const auto & boundary : _outlet_boundaries)
237 2051 : if (libmesh_map_find(_momentum_outlet_types, boundary) == "fixed-pressure-zero-gradient" ||
238 1009 : libmesh_map_find(_momentum_outlet_types, boundary) == "fixed-pressure")
239 1033 : outlet_boundaries_with_functors.push_back(boundary);
240 2012 : const auto & pressure_functors = getParam<std::vector<MooseFunctorName>>("pressure_functors");
241 1006 : if (outlet_boundaries_with_functors.size() != pressure_functors.size())
242 4 : paramError("pressure_functors",
243 2 : "Size (" + std::to_string(pressure_functors.size()) +
244 : ") is not the same as the number of pressure outlet boundaries in "
245 2 : "'fixed-pressure/fixed-pressure-zero-gradient' (size " +
246 2 : std::to_string(outlet_boundaries_with_functors.size()) + ")");
247 1004 : _pressure_functors = Moose::createMapFromVectors<BoundaryName, MooseFunctorName>(
248 : outlet_boundaries_with_functors, pressure_functors);
249 1004 : }
250 :
251 2334 : if (isParamSetByUser("momentum_wall_functors"))
252 : {
253 : // Not all wall boundary types require the specification of an inlet functor
254 : std::vector<BoundaryName> wall_boundaries_with_functors;
255 333 : for (const auto & boundary : _wall_boundaries)
256 264 : if (libmesh_map_find(_momentum_wall_types, boundary) == "noslip")
257 234 : wall_boundaries_with_functors.push_back(boundary);
258 : const auto & momentum_wall_functors =
259 138 : getParam<std::vector<std::vector<MooseFunctorName>>>("momentum_wall_functors");
260 69 : if (wall_boundaries_with_functors.size() != momentum_wall_functors.size())
261 0 : paramError("momentum_wall_functors",
262 0 : "Size (" + std::to_string(momentum_wall_functors.size()) +
263 : ") is not the same as the number of momentum_wall wall boundaries with "
264 0 : "no-slip boundary conditions ' (size " +
265 0 : std::to_string(wall_boundaries_with_functors.size()) + ")");
266 :
267 : _momentum_wall_functors =
268 69 : Moose::createMapFromVectors<BoundaryName, std::vector<MooseFunctorName>>(
269 : wall_boundaries_with_functors, momentum_wall_functors);
270 69 : }
271 :
272 1167 : addRequiredPhysicsTask("add_geometric_rm");
273 1167 : addRequiredPhysicsTask("add_variables_physics");
274 1167 : addRequiredPhysicsTask("add_ics_physics");
275 1167 : addRequiredPhysicsTask("add_materials_physics");
276 1167 : addRequiredPhysicsTask("add_user_object");
277 1167 : addRequiredPhysicsTask("add_postprocessor");
278 1167 : addRequiredPhysicsTask("add_corrector");
279 1167 : addRequiredPhysicsTask("get_turbulence_physics");
280 1167 : }
281 :
282 : void
283 1137 : WCNSFVFlowPhysicsBase::initializePhysicsAdditional()
284 : {
285 1137 : getProblem().needFV();
286 1137 : }
287 :
288 : void
289 14949 : WCNSFVFlowPhysicsBase::actOnAdditionalTasks()
290 : {
291 : // Turbulence physics would not be initialized before this task
292 14949 : if (_current_task == "get_turbulence_physics")
293 1129 : _turbulence_physics = getCoupledTurbulencePhysics();
294 14949 : }
295 :
296 : void
297 1107 : WCNSFVFlowPhysicsBase::addFVBCs()
298 : {
299 1107 : addInletBC();
300 1105 : addOutletBC();
301 1105 : addWallsBC();
302 1105 : addSeparatorBC();
303 1105 : }
304 :
305 : void
306 1115 : WCNSFVFlowPhysicsBase::addMaterials()
307 : {
308 1115 : if (hasForchheimerFriction() || _porous_medium_treatment)
309 461 : addPorousMediumSpeedMaterial();
310 : else
311 654 : addNonPorousMediumSpeedMaterial();
312 :
313 1115 : if (isParamValid(NS::fluid))
314 9 : addFluidPropertiesFunctorMaterial();
315 1115 : }
316 :
317 : void
318 461 : WCNSFVFlowPhysicsBase::addPorousMediumSpeedMaterial()
319 : {
320 461 : InputParameters params = getFactory().getValidParams("PINSFVSpeedFunctorMaterial");
321 461 : assignBlocks(params, _blocks);
322 :
323 1383 : for (unsigned int dim_i = 0; dim_i < dimension(); ++dim_i)
324 1844 : params.set<MooseFunctorName>(NS::superficial_velocity_vector[dim_i]) = _velocity_names[dim_i];
325 461 : if (_porous_medium_treatment)
326 443 : params.set<MooseFunctorName>(NS::porosity) = _flow_porosity_functor_name;
327 : else
328 36 : params.set<MooseFunctorName>(NS::porosity) = "1";
329 461 : params.set<bool>("define_interstitial_velocity_components") = _porous_medium_treatment;
330 :
331 1383 : getProblem().addFunctorMaterial(
332 461 : "PINSFVSpeedFunctorMaterial", prefix() + "pins_speed_material", params);
333 461 : }
334 :
335 : void
336 654 : WCNSFVFlowPhysicsBase::addNonPorousMediumSpeedMaterial()
337 : {
338 : // Not very future-proof but it works
339 654 : const bool use_ad = !dynamic_cast<WCNSLinearFVFlowPhysics *>(this);
340 : const std::string class_name =
341 823 : use_ad ? "ADVectorMagnitudeFunctorMaterial" : "VectorMagnitudeFunctorMaterial";
342 654 : InputParameters params = getFactory().getValidParams(class_name);
343 654 : assignBlocks(params, _blocks);
344 :
345 2616 : const std::vector<std::string> param_names{"x_functor", "y_functor", "z_functor"};
346 1927 : for (unsigned int dim_i = 0; dim_i < dimension(); ++dim_i)
347 2546 : params.set<MooseFunctorName>(param_names[dim_i]) = _velocity_names[dim_i];
348 1308 : params.set<MooseFunctorName>("vector_magnitude_name") = NS::speed;
349 :
350 1308 : getProblem().addFunctorMaterial(class_name, prefix() + "ins_speed_material", params);
351 2616 : }
352 :
353 : void
354 9 : WCNSFVFlowPhysicsBase::addFluidPropertiesFunctorMaterial()
355 : {
356 : // Not very future-proof but it works
357 9 : const bool use_ad = !dynamic_cast<WCNSLinearFVFlowPhysics *>(this);
358 : const std::string class_name =
359 9 : use_ad ? "GeneralFunctorFluidProps" : "NonADGeneralFunctorFluidProps";
360 9 : InputParameters params = getFactory().getValidParams(class_name);
361 9 : assignBlocks(params, _blocks);
362 :
363 9 : params.set<MooseFunctorName>(NS::pressure) = _pressure_name;
364 18 : params.set<MooseFunctorName>(NS::T_fluid) = _fluid_temperature_name;
365 9 : params.set<MooseFunctorName>(NS::speed) = NS::speed;
366 36 : params.applySpecificParameters(parameters(), {NS::fluid, NS::density, "mu_rampdown"});
367 9 : if (!MooseUtils::parsesToReal(_density_name))
368 9 : params.set<bool>("force_define_density") = true;
369 9 : if (!_porous_medium_treatment)
370 : {
371 18 : params.set<MooseFunctorName>(NS::porosity) = "1";
372 18 : params.set<MooseFunctorName>("characteristic_length") = "1";
373 : }
374 : else
375 : // not implemented yet
376 0 : paramInfo(
377 : NS::fluid,
378 : "Specifying the fluid properties user object does not define the GeneralFunctorFluidProps "
379 : "when using the porous medium treatment. You have to define this object in the input");
380 :
381 : // Dynamic pressure
382 9 : params.set<bool>("solving_for_dynamic_pressure") = _solve_for_dynamic_pressure;
383 9 : if (_solve_for_dynamic_pressure)
384 : {
385 0 : params.set<Point>("reference_pressure_point") = getParam<Point>("reference_pressure_point");
386 0 : if (!isParamSetByUser("reference_pressure_point"))
387 0 : paramWarning("reference_pressure_point",
388 : "Default value of (0,0,0) used. If this point is outside the flow domain, the "
389 : "simulation will error");
390 0 : params.set<Real>("reference_pressure") = getParam<Real>("reference_pressure");
391 : }
392 18 : params.set<Point>("gravity") = getParam<RealVectorValue>("gravity");
393 :
394 9 : if (!_porous_medium_treatment)
395 27 : getProblem().addFunctorMaterial(class_name, prefix() + "functor_fluidprops", params);
396 36 : }
397 :
398 : void
399 1123 : WCNSFVFlowPhysicsBase::addInitialConditions()
400 : {
401 1131 : if (!_define_variables && parameters().isParamSetByUser("initial_velocity") &&
402 2250 : parameters().isParamSetByUser("velocity_variable") &&
403 1127 : getParam<std::vector<FunctionName>>("initial_velocity").size() != 0)
404 : // TODO: Rework and remove this last statement once the NSFV action is removed
405 2 : paramError("initial_velocity",
406 : "Velocity is defined externally of WCNSFVFlowPhysicsBase, so should the inital "
407 : "conditions");
408 2242 : if (!_define_variables && parameters().isParamSetByUser("initial_pressure") &&
409 1123 : parameters().isParamSetByUser("pressure_variable"))
410 2 : paramError("initial_pressure",
411 : "Pressure is defined externally of WCNSFVFlowPhysicsBase, so should the inital "
412 : "condition");
413 :
414 : // Check dimension
415 4470 : if (getParam<std::vector<FunctionName>>("initial_velocity").size() != dimension() &&
416 2240 : getParam<std::vector<FunctionName>>("initial_velocity").size() != 3 &&
417 1123 : getParam<std::vector<FunctionName>>("initial_velocity").size() != 0)
418 : // TODO: Rework and remove this last statement once the NSFV action is removed
419 2 : paramError("initial_velocity",
420 4 : "The number of velocity components in the " + type() + " initial condition is not " +
421 2 : std::to_string(dimension()) + " or 3!");
422 :
423 1117 : InputParameters params = getFactory().getValidParams("FVFunctionIC");
424 1117 : assignBlocks(params, _blocks);
425 2234 : auto vvalue = getParam<std::vector<FunctionName>>("initial_velocity");
426 :
427 4433 : for (const auto d : make_range(dimension()))
428 : {
429 4398 : params.set<VariableName>("variable") = _velocity_names[d];
430 2199 : params.set<FunctionName>("function") = vvalue[d];
431 :
432 4398 : if (shouldCreateIC(_velocity_names[d],
433 : _blocks,
434 6597 : /*whether IC is a default*/ !isParamSetByUser("initial_velocity"),
435 4398 : /*error if already an IC*/ isParamSetByUser("initial_velocity")))
436 6297 : getProblem().addFVInitialCondition(
437 4198 : "FVFunctionIC", prefix() + _velocity_names[d] + "_ic", params);
438 : }
439 :
440 2234 : if (shouldCreateIC(_pressure_name,
441 : _blocks,
442 3351 : /*whether IC is a default*/ !isParamSetByUser("initial_pressure"),
443 2234 : /*error if already an IC*/ isParamSetByUser("initial_pressure")))
444 : {
445 2128 : params.set<VariableName>("variable") = _pressure_name;
446 3192 : params.set<FunctionName>("function") = getParam<FunctionName>("initial_pressure");
447 :
448 4256 : getProblem().addFVInitialCondition("FVFunctionIC", prefix() + _pressure_name + "_ic", params);
449 : }
450 1117 : }
451 :
452 : unsigned short
453 8235 : WCNSFVFlowPhysicsBase::getNumberAlgebraicGhostingLayersNeeded() const
454 : {
455 : unsigned short ghost_layers = 2;
456 8235 : return ghost_layers;
457 : }
458 :
459 : void
460 1115 : WCNSFVFlowPhysicsBase::addPostprocessors()
461 : {
462 2230 : const auto momentum_inlet_types = getParam<MultiMooseEnum>("momentum_inlet_types");
463 :
464 2514 : for (unsigned int bc_ind = 0; bc_ind < momentum_inlet_types.size(); ++bc_ind)
465 1399 : if (momentum_inlet_types[bc_ind] == "flux-mass" ||
466 1371 : momentum_inlet_types[bc_ind] == "flux-velocity")
467 : {
468 67 : const std::string pp_type = "AreaPostprocessor";
469 67 : InputParameters params = getFactory().getValidParams(pp_type);
470 201 : params.set<std::vector<BoundaryName>>("boundary") = {_inlet_boundaries[bc_ind]};
471 134 : params.set<ExecFlagEnum>("execute_on") = EXEC_INITIAL;
472 :
473 67 : const auto name_pp = "area_pp_" + _inlet_boundaries[bc_ind];
474 67 : if (!getProblem().hasUserObject(name_pp))
475 67 : getProblem().addPostprocessor(pp_type, name_pp, params);
476 67 : }
477 1115 : }
478 :
479 : VariableName
480 0 : WCNSFVFlowPhysicsBase::getFlowVariableName(const std::string & short_name) const
481 : {
482 0 : if (short_name == NS::pressure)
483 0 : return getPressureName();
484 0 : else if (short_name == NS::velocity_x && dimension() > 0)
485 : return getVelocityNames()[0];
486 0 : else if (short_name == NS::velocity_y && dimension() > 1)
487 : return getVelocityNames()[1];
488 0 : else if (short_name == NS::velocity_z && dimension() > 2)
489 : return getVelocityNames()[2];
490 0 : else if (short_name == NS::temperature)
491 0 : return getFluidTemperatureName();
492 : else
493 0 : mooseError("Short Variable name '", short_name, "' not recognized.");
494 : }
495 :
496 : MooseFunctorName
497 177 : WCNSFVFlowPhysicsBase::getPorosityFunctorName(bool smoothed) const
498 : {
499 177 : if (smoothed)
500 : return _flow_porosity_functor_name;
501 : else
502 : return _porosity_name;
503 : }
504 :
505 : const WCNSFVTurbulencePhysicsBase *
506 1129 : WCNSFVFlowPhysicsBase::getCoupledTurbulencePhysics() const
507 : {
508 : // User passed it, just use that
509 2258 : if (isParamValid("coupled_turbulence_physics"))
510 0 : return getCoupledPhysics<WCNSFVTurbulencePhysicsBase>(
511 : getParam<PhysicsName>("coupled_turbulence_physics"));
512 : // Look for any physics of the right type, and check the block restriction
513 : else
514 : {
515 1129 : const auto all_turbulence_physics = getCoupledPhysics<const WCNSFVTurbulencePhysicsBase>(true);
516 1129 : for (const auto physics : all_turbulence_physics)
517 : {
518 620 : if (checkBlockRestrictionIdentical(
519 : physics->name(), physics->blocks(), /*error_if_not_identical=*/false))
520 : return physics;
521 0 : else if (_verbose)
522 0 : mooseInfoRepeated("Detected Turbulence Physics '" + physics->name() +
523 : "' with an incompatible block restriction. It will thus not be coupled "
524 : "to this flow equations physics");
525 : }
526 1129 : }
527 : // Did not find one
528 509 : return nullptr;
529 : }
530 :
531 : const UserObjectName &
532 8460 : WCNSFVFlowPhysicsBase::rhieChowUOName() const
533 : {
534 : mooseAssert(!_rc_uo_name.empty(), "The Rhie-Chow user-object name should be set!");
535 8460 : return _rc_uo_name;
536 : }
537 :
538 : std::vector<SubdomainName>
539 997 : WCNSFVFlowPhysicsBase::getAxisymmetricRZBlocks() const
540 : {
541 : std::vector<SubdomainName> rz_blocks;
542 997 : const auto & mesh = getProblem().mesh();
543 :
544 : const bool use_all_blocks =
545 997 : _blocks.empty() || allMeshBlocks(_blocks) ||
546 997 : std::find(_blocks.begin(), _blocks.end(), "ANY_BLOCK_ID") != _blocks.end();
547 :
548 : std::vector<SubdomainID> block_ids;
549 997 : if (use_all_blocks)
550 : {
551 989 : const auto & mesh_blocks = mesh.meshSubdomains();
552 989 : block_ids.insert(block_ids.end(), mesh_blocks.begin(), mesh_blocks.end());
553 : }
554 : else
555 16 : block_ids = mesh.getSubdomainIDs(_blocks);
556 :
557 2249 : for (const auto subdomain_id : block_ids)
558 1252 : if (mesh.getCoordSystem(subdomain_id) == Moose::COORD_RZ)
559 : {
560 45 : auto name = mesh.getSubdomainName(subdomain_id);
561 45 : if (name.empty())
562 90 : name = Moose::stringify(subdomain_id);
563 45 : rz_blocks.push_back(name);
564 : }
565 :
566 997 : return rz_blocks;
567 997 : }
568 :
569 : void
570 937 : WCNSFVFlowPhysicsBase::addAxisymmetricViscousSource()
571 : {
572 937 : if (!_has_flow_equations || !_add_rz_viscous_source)
573 892 : return;
574 :
575 937 : const auto rz_blocks = getAxisymmetricRZBlocks();
576 937 : if (rz_blocks.empty())
577 : return;
578 :
579 45 : const auto radial_index = getProblem().mesh().getAxisymmetricRadialCoord();
580 45 : addAxisymmetricViscousSourceKernel(rz_blocks, radial_index);
581 937 : }
|