LCOV - code coverage report
Current view: top level - src/physics - WCNSLinearFVFlowPhysics.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: #32971 (54bef8) with base c6cf66 Lines: 340 396 85.9 %
Date: 2026-05-29 20:37:52 Functions: 19 19 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14