https://mooseframework.inl.gov
Loading...
Searching...
No Matches
LinearFVPressureFluxBC.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://www.mooseframework.org
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
11#include "NS.h"
12
14
17{
20 "Adds a fixed diffusive flux BC which can be used for the assembly of linear "
21 "finite volume system and whose normal face gradient values are determined "
22 "using the H/A flux and a prescribed boundary velocity. This boundary condition is only "
23 "designed to work with advection-diffusion problems.");
24 params.addRequiredParam<MooseFunctorName>("HbyA_flux", "The total HbyA face flux value.");
25 params.addRequiredParam<MooseFunctorName>(
26 "Ainv", "The 1/A where A is the momentum system diagonal vector.");
27 params.addParam<bool>(
28 "use_two_term_expansion",
29 true,
30 "Whether to reconstruct the boundary pressure using the pressure flux and cell gradient. If "
31 "false, the boundary pressure is approximated by the adjacent cell pressure.");
32 params.addRequiredParam<MooseFunctorName>("u", "The x-velocity functor on the boundary.");
33 params.addParam<MooseFunctorName>("v", "The y-velocity functor on the boundary.");
34 params.addParam<MooseFunctorName>("w", "The z-velocity functor on the boundary.");
35 params.addRequiredParam<MooseFunctorName>(
36 NS::density, "The density functor used together with the prescribed boundary velocity.");
37 return params;
38}
39
41 : LinearFVAdvectionDiffusionBC(parameters),
42 _HbyA_flux(getFunctor<Real>("HbyA_flux")),
43 _Ainv(getFunctor<RealVectorValue>("Ainv")),
44 _dim(_subproblem.mesh().dimension()),
45 _two_term_expansion(getParam<bool>("use_two_term_expansion")),
46 _u(getFunctor<Real>("u")),
47 _v(parameters.isParamValid("v") ? &getFunctor<Real>("v") : nullptr),
48 _w(parameters.isParamValid("w") ? &getFunctor<Real>("w") : nullptr),
49 _rho(getFunctor<Real>(NS::density))
50{
51 if (_dim >= 2 && !_v)
52 paramError("v", "The 'v' boundary velocity functor must be provided for 2D and 3D problems.");
53
54 if (_dim >= 3 && !_w)
55 paramError("w", "The 'w' boundary velocity functor must be provided for 3D problems.");
56
57 if (_dim < 2 && _v)
58 paramError("v", "The 'v' boundary velocity functor is only valid in 2D and 3D problems.");
59
60 if (_dim < 3 && _w)
61 paramError("w", "The 'w' boundary velocity functor is only valid in 3D problems.");
62
65}
66
67Real
69{
70 const auto face_arg = singleSidedFaceArg(_current_face_info);
71 const auto state = determineState();
72
73 Real required_pressure_flux = _HbyA_flux(face_arg, state);
74 const auto & normal = _current_face_info->normal();
75 Real boundary_velocity_dot_normal = _u(face_arg, state) * normal(0);
76
77 if (_dim >= 2)
78 boundary_velocity_dot_normal += (*_v)(face_arg, state) * normal(1);
79
80 if (_dim >= 3)
81 boundary_velocity_dot_normal += (*_w)(face_arg, state) * normal(2);
82
83 // FaceInfo normals point from element to neighbor, so reverse the prescribed velocity flux when
84 // this boundary condition acts on the neighbor side of an internal face.
85 const Real boundary_normal_multiplier =
86 _current_face_type == FaceInfo::VarFaceNeighbors::ELEM ? 1.0 : -1.0;
87 required_pressure_flux +=
88 _rho(face_arg, state) * boundary_normal_multiplier * boundary_velocity_dot_normal;
89
90 return required_pressure_flux;
91}
92
93Real
95{
96 const auto face_arg = singleSidedFaceArg(_current_face_info);
97 const auto face_ainv = _Ainv(face_arg, determineState());
98 const auto & normal = _current_face_info->normal();
99
100 // Match the boundary-normal coefficient used by LinearFVAnisotropicDiffusion:
101 // for a diagonal tensor Ainv, the effective normal coefficient is n^T Ainv n.
102 Real normal_ainv = 0.0;
103 for (const auto i : make_range(_dim))
104 normal_ainv += normal(i) * normal(i) * face_ainv(i);
105
106 if (normal_ainv < 0.0)
107 mooseError("The boundary-normal Ainv coefficient must be nonnegative, but its value is ",
108 normal_ainv,
109 ".");
110
111 return normal_ainv;
112}
113
114Real
116{
117 const auto state = determineState();
118 const auto elem_info = _current_face_type == FaceInfo::VarFaceNeighbors::ELEM
121
123 return _var.getElemValue(*elem_info, state);
124
125 const Real normal_ainv = computeBoundaryAinv();
126
127 // Ainv is initialized to zero and is first populated by the momentum assembly. Until then, use
128 // the cell pressure (1 term expansion) for the initial pressure-gradient
129 // calculation.
130 if (normal_ainv == 0.0)
131 return _var.getElemValue(*elem_info, state);
132
133 const Real distance = computeCellToFaceDistance();
134 const auto d_cf = computeCellToFaceVector();
135 const auto & face_normal = _current_face_info->normal();
136 const auto tangential_cell_to_face = d_cf - (d_cf * face_normal) * face_normal;
137
138 // Return the 2-term expansion for the boundary value
139 return _var.getElemValue(*elem_info, state) + computeBoundaryNormalGradient() * distance +
140 _var.gradSln(*elem_info, state) * tangential_cell_to_face;
141}
142
143Real
145{
147 return 0.0;
148
149 const Real normal_ainv = computeBoundaryAinv();
150 if (normal_ainv == 0.0)
151 return 0.0;
152
153 const auto state = determineState();
154 const auto face_ainv = _Ainv(singleSidedFaceArg(_current_face_info), state);
155 const auto elem_info = _current_face_type == FaceInfo::VarFaceNeighbors::ELEM
158 const Real boundary_normal_multiplier =
159 _current_face_type == FaceInfo::VarFaceNeighbors::ELEM ? 1.0 : -1.0;
160 const auto boundary_normal = boundary_normal_multiplier * _current_face_info->normal();
161
162 RealVectorValue normal_scaled_ainv;
163 for (const auto i : make_range(_dim))
164 normal_scaled_ainv(i) = boundary_normal(i) * face_ainv(i);
165
166 // The prescribed pressure flux is the complete tensor-weighted flux. Subtract its tangential
167 // part only when inverting that flux to reconstruct the boundary-normal pressure gradient.
168 const auto tangential_ainv = normal_scaled_ainv - normal_ainv * boundary_normal;
169 const Real tangential_pressure_flux = tangential_ainv * _var.gradSln(*elem_info, state);
170
171 return (-computeRequiredPressureFlux() - tangential_pressure_flux) / normal_ainv;
172}
173
174Real
179
180Real
182{
183 const auto elem_info = _current_face_type == FaceInfo::VarFaceNeighbors::ELEM
186 return computeBoundaryValue() - _var.getElemValue(*elem_info, determineState());
187}
188
189Real
194
195Real
registerMooseObject("NavierStokesApp", LinearFVPressureFluxBC)
const Point & normal() const
const ElemInfo * elemInfo() const
const ElemInfo * neighborInfo() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
static InputParameters validParams()
const FaceInfo * _current_face_info
Moose::FaceArg singleSidedFaceArg(const FaceInfo *fi, Moose::FV::LimiterType limiter_type=Moose::FV::LimiterType::CentralDifference, bool correct_skewness=false) const
Real computeCellToFaceDistance() const
FaceInfo::VarFaceNeighbors _current_face_type
RealVectorValue computeCellToFaceVector() const
MooseLinearVariableFV< Real > & _var
Class implementing a flux boundary condition for linear finite volume pressure variables used in the ...
virtual Real computeBoundaryGradientMatrixContribution() const override
const Moose::Functor< RealVectorValue > & _Ainv
The functor for the 1/A tensor serving as a diffusion coefficient.
LinearFVPressureFluxBC(const InputParameters &parameters)
Class constructor.
virtual Real computeBoundaryValue() const override
const unsigned short _dim
Spatial dimension of the mesh.
Real computeBoundaryAinv() const
Compute the scalar A^{-1} coefficient, which is zero before the first momentum assembly.
virtual Real computeBoundaryValueRHSContribution() const override
const Moose::Functor< Real > & _u
Velocity functors used to prescribe a boundary mass flux.
virtual Real computeBoundaryNormalGradient() const override
const Moose::Functor< Real > & _rho
Density functor used with the prescribed boundary velocity.
const Moose::Functor< Real > *const _w
const Moose::Functor< Real > *const _v
virtual Real computeBoundaryValueMatrixContribution() const override
static InputParameters validParams()
Real computeRequiredPressureFlux() const
Compute the required boundary pressure flux contribution.
const bool _two_term_expansion
Whether to reconstruct the boundary pressure with the pressure flux and cell gradient.
virtual Real computeBoundaryGradientRHSContribution() const override
const Moose::Functor< Real > & _HbyA_flux
The H/A flux functor for this BC (can be variable, function, etc)
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
Real getElemValue(const ElemInfo &elem_info, const StateArg &state) const
VectorValue< Real > gradSln(const ElemInfo &elem_info, const StateArg &state) const
const LinearFVGradientReader & requestCellGradients()
Moose::StateArg determineState() const
MeshBase & mesh
static const std::string density
Definition NS.h:34
Real distance(const Point &p)