LCOV - code coverage report
Current view: top level - src/fvbcs - INSFVMomentumAdvectionOutflowBC.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 9fc4b0 Lines: 44 58 75.9 %
Date: 2025-08-14 10:14:56 Functions: 4 5 80.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 "INSFVMomentumAdvectionOutflowBC.h"
      11             : #include "INSFVVelocityVariable.h"
      12             : #include "SubProblem.h"
      13             : #include "MooseMesh.h"
      14             : #include "NS.h"
      15             : #include "SystemBase.h"
      16             : 
      17             : registerMooseObject("NavierStokesApp", INSFVMomentumAdvectionOutflowBC);
      18             : 
      19             : InputParameters
      20         662 : INSFVMomentumAdvectionOutflowBC::validParams()
      21             : {
      22         662 :   InputParameters params = INSFVFluxBC::validParams();
      23         662 :   params += INSFVFullyDevelopedFlowBC::validParams();
      24        1324 :   params.addRequiredParam<MooseFunctorName>("u", "The velocity in the x direction.");
      25        1324 :   params.addParam<MooseFunctorName>("v", "The velocity in the y direction.");
      26        1324 :   params.addParam<MooseFunctorName>("w", "The velocity in the z direction.");
      27         662 :   params.addClassDescription("Fully developed outflow boundary condition for advecting momentum. "
      28             :                              "This will impose a zero normal gradient on the boundary velocity.");
      29         662 :   params.addRequiredParam<MooseFunctorName>(NS::density, "The density");
      30         662 :   return params;
      31           0 : }
      32             : 
      33         396 : INSFVMomentumAdvectionOutflowBC::INSFVMomentumAdvectionOutflowBC(const InputParameters & params)
      34             :   : INSFVFluxBC(params),
      35             :     INSFVFullyDevelopedFlowBC(params),
      36         396 :     _u(getFunctor<ADReal>("u")),
      37        1584 :     _v(isParamValid("v") ? &getFunctor<ADReal>("v") : nullptr),
      38         792 :     _w(isParamValid("w") ? &getFunctor<ADReal>("w") : nullptr),
      39         396 :     _dim(_subproblem.mesh().dimension()),
      40         792 :     _rho(getFunctor<ADReal>(NS::density))
      41             : {
      42         396 :   if (_dim >= 2 && !_v)
      43           0 :     mooseError(
      44             :         "In two or more dimensions, the v velocity must be supplied using the 'v' parameter");
      45         396 :   if (_dim >= 3 && !_w)
      46           0 :     mooseError("In three dimensions, the w velocity must be supplied using the 'w' parameter");
      47         396 : }
      48             : 
      49             : ADReal
      50       31376 : INSFVMomentumAdvectionOutflowBC::computeAdvectedQuantity(const Moose::FaceArg & boundary_face,
      51             :                                                          const Moose::StateArg & state)
      52             : {
      53       31376 :   const auto rho_boundary = _rho(boundary_face, state);
      54       31376 :   const auto eps_boundary = epsFunctor()(boundary_face, state);
      55             : 
      56             :   // This will tend to be an extrapolated boundary for the velocity in which case, when using two
      57             :   // term expansion, this boundary value will actually be a function of more than just the degree of
      58             :   // freedom at the cell centroid adjacent to the face, e.g. it can/will depend on surrounding cell
      59             :   // degrees of freedom as well
      60       31376 :   const auto var_boundary = _var(boundary_face, state);
      61             : 
      62       31376 :   return rho_boundary / eps_boundary * var_boundary;
      63             : }
      64             : 
      65             : ADReal
      66           0 : INSFVMomentumAdvectionOutflowBC::computeSegregatedContribution()
      67             : {
      68           0 :   const auto boundary_face = singleSidedFaceArg();
      69           0 :   const auto state = determineState();
      70           0 :   return _normal *
      71           0 :          _rc_uo.getVelocity(Moose::FV::InterpMethod::RhieChow,
      72           0 :                             *_face_info,
      73           0 :                             determineState(),
      74             :                             _tid,
      75             :                             /*subtract_mesh_velocity=*/true) *
      76           0 :          computeAdvectedQuantity(boundary_face, state);
      77             : }
      78             : 
      79             : void
      80       31376 : INSFVMomentumAdvectionOutflowBC::gatherRCData(const FaceInfo & fi)
      81             : {
      82             :   using namespace Moose::FV;
      83             : 
      84       31376 :   _face_info = &fi;
      85       31376 :   _normal = fi.normal();
      86       31376 :   _face_type = fi.faceType(std::make_pair(_var.number(), _var.sys().number()));
      87             : 
      88       31376 :   if (_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
      89           0 :     _normal = -_normal;
      90             : 
      91       31376 :   const auto boundary_face = singleSidedFaceArg();
      92       31376 :   const auto state = determineState();
      93       62752 :   ADRealVectorValue v(_u(boundary_face, state));
      94       31376 :   if (_v)
      95       31376 :     v(1) = (*_v)(boundary_face, state);
      96       31376 :   if (_w)
      97           0 :     v(2) = (*_w)(boundary_face, state);
      98             : 
      99       31376 :   const auto & elem = (_face_type == FaceInfo::VarFaceNeighbors::ELEM) ? _face_info->elem()
     100           0 :                                                                        : _face_info->neighbor();
     101             : 
     102             :   // This will tend to be an extrapolated boundary for the velocity in which case, when using two
     103             :   // term expansion, this boundary value will actually be a function of more than just the degree of
     104             :   // freedom at the cell centroid adjacent to the face, e.g. it can/will depend on surrounding cell
     105             :   // degrees of freedom as well
     106       31376 :   const auto dof_number = elem.dof_number(_sys.number(), _var.number(), 0);
     107       31376 :   const auto advected_quant = computeAdvectedQuantity(boundary_face, state);
     108       62752 :   const auto a = advected_quant.derivatives()[dof_number] * _normal * v;
     109             : 
     110       31376 :   const auto strong_resid = _normal * v * advected_quant;
     111             : 
     112       62752 :   _rc_uo.addToA((_face_type == FaceInfo::VarFaceNeighbors::ELEM) ? fi.elemPtr() : fi.neighborPtr(),
     113       31376 :                 _index,
     114       31376 :                 a * (fi.faceArea() * fi.faceCoord()));
     115             : 
     116       62752 :   addResidualAndJacobian(strong_resid * (fi.faceArea() * fi.faceCoord()));
     117       31376 : }

Generated by: LCOV version 1.14