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 : }