LCOV - code coverage report
Current view: top level - src/physics - WCNSLinearFVScalarTransportPhysics.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: #33416 (b10b36) with base 9fbd27 Lines: 120 146 82.2 %
Date: 2026-07-23 16:18:21 Functions: 11 11 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 "WCNSLinearFVScalarTransportPhysics.h"
      11             : #include "WCNSFVFlowPhysicsBase.h"
      12             : #include "NSFVUtils.h"
      13             : #include "NS.h"
      14             : 
      15             : registerNavierStokesPhysicsBaseTasks("NavierStokesApp", WCNSLinearFVScalarTransportPhysics);
      16             : registerWCNSFVScalarTransportBaseTasks("NavierStokesApp", WCNSLinearFVScalarTransportPhysics);
      17             : registerMooseAction("NavierStokesApp",
      18             :                     WCNSLinearFVScalarTransportPhysics,
      19             :                     "add_interpolation_method_physics");
      20             : 
      21             : InputParameters
      22          67 : WCNSLinearFVScalarTransportPhysics::validParams()
      23             : {
      24          67 :   InputParameters params = WCNSFVScalarTransportPhysicsBase::validParams();
      25          67 :   params.addClassDescription("Define the Navier Stokes weakly-compressible scalar field transport "
      26             :                              "equation(s) using the linear finite volume discretization");
      27          67 :   params.set<MooseEnum>("passive_scalar_advection_interpolation") =
      28         201 :       NS::fvAdvectedInterpolationMethods();
      29         134 :   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         134 :   params.addParam<bool>("use_nonorthogonal_correction",
      34         134 :                         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          67 :   params.suppressParameter<MooseEnum>("preconditioning");
      40             : 
      41         134 :   params.addParamNamesToGroup("passive_scalar_advection_interpolation_method_name",
      42             :                               "Numerical scheme");
      43             : 
      44          67 :   return params;
      45           0 : }
      46             : 
      47          67 : WCNSLinearFVScalarTransportPhysics::WCNSLinearFVScalarTransportPhysics(
      48          67 :     const InputParameters & parameters)
      49          67 :   : WCNSFVScalarTransportPhysicsBase(parameters)
      50             : {
      51          67 :   addRequiredPhysicsTask("add_interpolation_method_physics");
      52             : 
      53          67 :   if (_porous_medium_treatment)
      54           0 :     _flow_equations_physics->paramError("porous_medium_treatment",
      55             :                                         "Porous media scalar advection is currently unimplemented");
      56          67 : }
      57             : 
      58             : void
      59          67 : WCNSLinearFVScalarTransportPhysics::addFVInterpolationMethods()
      60             : {
      61         201 :   if (!_has_scalar_equation || isParamValid("passive_scalar_advection_interpolation_method_name"))
      62             :     return;
      63             : 
      64         183 :   addFVAdvectedInterpolationMethod(getParam<MooseEnum>("passive_scalar_advection_interpolation"));
      65             : }
      66             : 
      67             : void
      68          67 : WCNSLinearFVScalarTransportPhysics::addSolverVariables()
      69             : {
      70             :   // For compatibility with Modules/NavierStokesFV syntax
      71          67 :   if (!_has_scalar_equation)
      72           0 :     return;
      73             : 
      74          67 :   auto params = getFactory().getValidParams("MooseLinearVariableFVReal");
      75          67 :   assignBlocks(params, _blocks);
      76             : 
      77         160 :   for (const auto name_i : index_range(_passive_scalar_names))
      78             :   {
      79             :     // Dont add if the user already defined the variable
      80         186 :     if (!shouldCreateVariable(_passive_scalar_names[name_i], _blocks, /*error if aux*/ true))
      81             :     {
      82           0 :       reportPotentiallyMissedParameters({"system_names", "passive_scalar_scaling"},
      83             :                                         "MooseLinearVariableFVReal");
      84           0 :       continue;
      85             :     }
      86             : 
      87          93 :     params.set<SolverSystemName>("solver_sys") = getSolverSystem(name_i);
      88         186 :     if (isParamValid("passive_scalar_scaling"))
      89           0 :       params.set<std::vector<Real>>("scaling") = {
      90           0 :           getParam<std::vector<Real>>("passive_scalar_scaling")[name_i]};
      91             : 
      92         186 :     getProblem().addVariable("MooseLinearVariableFVReal", _passive_scalar_names[name_i], params);
      93             :   }
      94          67 : }
      95             : 
      96             : void
      97          17 : WCNSLinearFVScalarTransportPhysics::addScalarTimeKernels()
      98             : {
      99          17 :   std::string kernel_type = "LinearFVTimeDerivative";
     100          17 :   InputParameters params = getFactory().getValidParams(kernel_type);
     101          17 :   assignBlocks(params, _blocks);
     102             : 
     103          42 :   for (const auto & vname : _passive_scalar_names)
     104             :   {
     105          50 :     params.set<LinearVariableName>("variable") = vname;
     106          50 :     if (shouldCreateTimeDerivative(vname, _blocks, /*error if already defined */ false))
     107         100 :       getProblem().addLinearFVKernel(kernel_type, prefix() + "ins_" + vname + "_time", params);
     108             :   }
     109          34 : }
     110             : 
     111             : void
     112          67 : WCNSLinearFVScalarTransportPhysics::addScalarAdvectionKernels()
     113             : {
     114             :   const auto method_name =
     115          67 :       isParamValid("passive_scalar_advection_interpolation_method_name")
     116          67 :           ? getParam<InterpolationMethodName>("passive_scalar_advection_interpolation_method_name")
     117             :           : InterpolationMethodName(
     118         262 :                 std::string(getParam<MooseEnum>("passive_scalar_advection_interpolation")));
     119             : 
     120          67 :   const std::string kernel_type = "LinearFVScalarAdvection";
     121          67 :   InputParameters params = getFactory().getValidParams(kernel_type);
     122             : 
     123          67 :   assignBlocks(params, _blocks);
     124          67 :   params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName();
     125          67 :   params.set<InterpolationMethodName>("advected_interp_method_name") = method_name;
     126          67 :   setSlipVelocityParams(params);
     127             : 
     128         160 :   for (const auto & vname : _passive_scalar_names)
     129             :   {
     130         186 :     params.set<LinearVariableName>("variable") = vname;
     131         372 :     getProblem().addLinearFVKernel(kernel_type, prefix() + "ins_" + vname + "_advection", params);
     132             :   }
     133         134 : }
     134             : 
     135             : void
     136          67 : WCNSLinearFVScalarTransportPhysics::addScalarDiffusionKernels()
     137             : {
     138             :   // Direct specification of diffusion term
     139             :   const auto passive_scalar_diffusivities =
     140         201 :       getParam<std::vector<MooseFunctorName>>("passive_scalar_diffusivity");
     141             : 
     142          67 :   if (passive_scalar_diffusivities.size())
     143             :   {
     144          53 :     const std::string kernel_type = "LinearFVDiffusion";
     145          53 :     InputParameters params = getFactory().getValidParams(kernel_type);
     146          53 :     assignBlocks(params, _blocks);
     147          53 :     params.set<bool>("use_nonorthogonal_correction") =
     148         159 :         getParam<bool>("use_nonorthogonal_correction");
     149         132 :     for (const auto name_i : index_range(_passive_scalar_names))
     150             :     {
     151         158 :       params.set<LinearVariableName>("variable") = _passive_scalar_names[name_i];
     152         158 :       params.set<MooseFunctorName>("diffusion_coeff") =
     153         158 :           passive_scalar_diffusivities[name_i] + (_has_turbulence_model ? "_plus_mut/Sc_t" : "");
     154         158 :       getProblem().addLinearFVKernel(
     155         237 :           kernel_type, prefix() + "ins_" + _passive_scalar_names[name_i] + "_diffusion", params);
     156             :     }
     157          53 :   }
     158          67 : }
     159             : 
     160             : void
     161          30 : WCNSLinearFVScalarTransportPhysics::addScalarSourceKernels()
     162             : {
     163          30 :   const std::string kernel_type = "LinearFVSource";
     164          30 :   InputParameters params = getFactory().getValidParams(kernel_type);
     165          30 :   assignBlocks(params, _blocks);
     166             : 
     167          66 :   for (const auto scalar_i : index_range(_passive_scalar_names))
     168             :   {
     169          72 :     params.set<LinearVariableName>("variable") = _passive_scalar_names[scalar_i];
     170             : 
     171          36 :     if (_passive_scalar_sources.size())
     172             :     {
     173             :       // Added for backward compatibility with former Modules/NavierStokesFV syntax
     174          24 :       params.set<MooseFunctorName>("source_density") = _passive_scalar_sources[scalar_i];
     175          48 :       getProblem().addLinearFVKernel(
     176          72 :           kernel_type, prefix() + "ins_" + _passive_scalar_names[scalar_i] + "_source", params);
     177             :     }
     178             : 
     179          36 :     if (_passive_scalar_coupled_sources.size())
     180          24 :       for (const auto i : index_range(_passive_scalar_coupled_sources[scalar_i]))
     181             :       {
     182          24 :         params.set<MooseFunctorName>("source_density") =
     183             :             _passive_scalar_coupled_sources[scalar_i][i];
     184          12 :         if (_passive_scalar_sources_coef.size())
     185           0 :           params.set<Real>("scaling_factor") = _passive_scalar_sources_coef[scalar_i][i];
     186             : 
     187          24 :         getProblem().addLinearFVKernel(kernel_type,
     188          36 :                                        prefix() + "ins_" + _passive_scalar_names[scalar_i] +
     189          36 :                                            "_coupled_source_" + std::to_string(i),
     190             :                                        params);
     191             :       }
     192             :   }
     193          60 : }
     194             : 
     195             : void
     196          67 : WCNSLinearFVScalarTransportPhysics::addScalarInletBC()
     197             : {
     198          67 :   const auto & inlet_boundaries = _flow_equations_physics->getInletBoundaries();
     199          67 :   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          58 :   if (inlet_boundaries.size() * _passive_scalar_names.size() != _passive_scalar_inlet_types.size())
     206           0 :     paramError(
     207             :         "passive_scalar_inlet_types",
     208           0 :         "The number of scalar inlet types (" + std::to_string(_passive_scalar_inlet_types.size()) +
     209           0 :             ") is not equal to the number of inlet boundaries (" +
     210           0 :             std::to_string(inlet_boundaries.size()) + ") times the number of passive scalars (" +
     211           0 :             std::to_string(_passive_scalar_names.size()) + ")");
     212          58 :   if (_passive_scalar_names.size() != _passive_scalar_inlet_functors.size())
     213           0 :     paramError("passive_scalar_inlet_functors",
     214           0 :                "The number of groups of inlet functors (" +
     215           0 :                    std::to_string(_passive_scalar_inlet_functors.size()) +
     216           0 :                    ") is not equal to the number of passive scalars (" +
     217           0 :                    std::to_string(_passive_scalar_names.size()) + ")");
     218             : 
     219         142 :   for (const auto name_i : index_range(_passive_scalar_names))
     220             :   {
     221          84 :     if (inlet_boundaries.size() != _passive_scalar_inlet_functors[name_i].size())
     222           0 :       paramError("passive_scalar_inlet_functors",
     223           0 :                  "The number of inlet boundary functors for scalar '" +
     224           0 :                      _passive_scalar_names[name_i] +
     225           0 :                      "' does not match the number of inlet boundaries (" +
     226           0 :                      std::to_string(_passive_scalar_inlet_functors[name_i].size()) + ")");
     227             : 
     228          84 :     unsigned int num_inlets = inlet_boundaries.size();
     229         168 :     for (unsigned int bc_ind = 0; bc_ind < num_inlets; ++bc_ind)
     230             :     {
     231          84 :       if (_passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "fixed-value")
     232             :       {
     233          84 :         const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC";
     234          84 :         InputParameters params = getFactory().getValidParams(bc_type);
     235         168 :         params.set<LinearVariableName>("variable") = _passive_scalar_names[name_i];
     236         168 :         params.set<MooseFunctorName>("functor") = _passive_scalar_inlet_functors[name_i][bc_ind];
     237         252 :         params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]};
     238             : 
     239         168 :         getProblem().addLinearFVBC(
     240          84 :             bc_type, _passive_scalar_names[name_i] + "_" + inlet_boundaries[bc_ind], params);
     241          84 :       }
     242           0 :       else if (_passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "flux-mass" ||
     243           0 :                _passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "flux-velocity")
     244             :       {
     245           0 :         mooseError("Flux boundary conditions not supported at this time using the linear finite "
     246             :                    "volume discretization");
     247             :       }
     248             :     }
     249             :   }
     250             : }
     251             : 
     252             : unsigned short
     253         201 : WCNSLinearFVScalarTransportPhysics::getNumberAlgebraicGhostingLayersNeeded() const
     254             : {
     255         201 :   return 1;
     256             : }
     257             : 
     258             : void
     259          67 : WCNSLinearFVScalarTransportPhysics::addScalarOutletBC()
     260             : {
     261          67 :   const auto & outlet_boundaries = _flow_equations_physics->getOutletBoundaries();
     262          67 :   if (outlet_boundaries.empty())
     263             :     return;
     264             : 
     265         116 :   for (const auto & outlet_bdy : outlet_boundaries)
     266             :   {
     267          58 :     const std::string bc_type = "LinearFVAdvectionDiffusionOutflowBC";
     268          58 :     InputParameters params = getFactory().getValidParams(bc_type);
     269         174 :     params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy};
     270          58 :     params.set<bool>("use_two_term_expansion") =
     271         174 :         getParam<bool>("passive_scalar_two_term_bc_expansion");
     272             : 
     273         142 :     for (const auto name_i : index_range(_passive_scalar_names))
     274             :     {
     275         168 :       params.set<LinearVariableName>("variable") = _passive_scalar_names[name_i];
     276         168 :       getProblem().addLinearFVBC(bc_type, _passive_scalar_names[name_i] + "_" + outlet_bdy, params);
     277             :     }
     278          58 :   }
     279             : }

Generated by: LCOV version 1.14