https://mooseframework.inl.gov
PCNSFVStrongBC.C
Go to the documentation of this file.
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 "PCNSFVStrongBC.h"
11 #include "NS.h"
13 #include "Function.h"
14 #include "MfrPostprocessor.h"
15 
16 registerMooseObject("NavierStokesApp", PCNSFVStrongBC);
17 
20 {
22  params.addClassDescription("Computes the residual of advective term using finite volume method.");
23  params.addRequiredParam<UserObjectName>(NS::fluid, "Fluid properties userobject");
24  MooseEnum eqn("mass momentum energy scalar");
25  params.addRequiredParam<MooseEnum>("eqn", eqn, "The equation you're solving.");
26  MooseEnum momentum_component("x=0 y=1 z=2");
27  params.addParam<MooseEnum>("momentum_component",
28  momentum_component,
29  "The component of the momentum equation that this kernel applies to.");
30  params.addParam<bool>("velocity_function_includes_rho",
31  false,
32  "Whether the provided superficial velocity function actually includes "
33  "multiplication by rho (e.g. the function is representative of momentum.");
34  params.addParam<FunctionName>(
36  "An optional name of a vector function for the velocity. If not provided then the "
37  "superficial velocity will be treated implicitly (e.g. we will use the interior value");
38  params.addParam<FunctionName>(
40  "An optional name of a function for the pressure. If not provided then the pressure will be "
41  "treated implicitly (e.g. we will use the interior value");
42  params.addParam<FunctionName>(
44  "An optional name of a function for the fluid temperature. If not provided then the fluid "
45  "temperature will be treated implicitly (e.g. we will use the interior value");
46  params.addParam<FunctionName>(
47  "scalar",
48  "A function describing the value of the scalar at the boundary. If this function is not "
49  "provided, then the interior value will be used.");
50  params.addParam<UserObjectName>("mfr_postprocessor",
51  "A postprocessor used for outputting mass flow rates on the same "
52  "boundary this object acts on");
53  return params;
54 }
55 
57  : FVFluxBC(params),
58  _fluid(getUserObject<SinglePhaseFluidProperties>(NS::fluid)),
59  _dim(_mesh.dimension()),
60  _sup_vel_x_elem(getADMaterialProperty<Real>(NS::superficial_velocity_x)),
61  _sup_vel_x_neighbor(getNeighborADMaterialProperty<Real>(NS::superficial_velocity_x)),
62  _grad_sup_vel_x_elem(
63  getADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_x))),
64  _grad_sup_vel_x_neighbor(
65  getNeighborADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_x))),
66  _sup_vel_y_elem(getADMaterialProperty<Real>(NS::superficial_velocity_y)),
67  _sup_vel_y_neighbor(getNeighborADMaterialProperty<Real>(NS::superficial_velocity_y)),
68  _grad_sup_vel_y_elem(
69  getADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_y))),
70  _grad_sup_vel_y_neighbor(
71  getNeighborADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_y))),
72  _sup_vel_z_elem(getADMaterialProperty<Real>(NS::superficial_velocity_z)),
73  _sup_vel_z_neighbor(getNeighborADMaterialProperty<Real>(NS::superficial_velocity_z)),
74  _grad_sup_vel_z_elem(
75  getADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_z))),
76  _grad_sup_vel_z_neighbor(
77  getNeighborADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_z))),
78  _T_fluid_elem(getADMaterialProperty<Real>(NS::T_fluid)),
79  _T_fluid_neighbor(getNeighborADMaterialProperty<Real>(NS::T_fluid)),
80  _grad_T_fluid_elem(getADMaterialProperty<RealVectorValue>(NS::grad(NS::T_fluid))),
81  _grad_T_fluid_neighbor(getNeighborADMaterialProperty<RealVectorValue>(NS::grad(NS::T_fluid))),
82  _pressure_elem(getADMaterialProperty<Real>(NS::pressure)),
83  _pressure_neighbor(getNeighborADMaterialProperty<Real>(NS::pressure)),
84  _grad_pressure_elem(getADMaterialProperty<RealVectorValue>(NS::grad(NS::pressure))),
85  _grad_pressure_neighbor(getNeighborADMaterialProperty<RealVectorValue>(NS::grad(NS::pressure))),
86  _eps_elem(getMaterialProperty<Real>(NS::porosity)),
87  _eps_neighbor(getNeighborMaterialProperty<Real>(NS::porosity)),
88  _eqn(getParam<MooseEnum>("eqn")),
89  _index(getParam<MooseEnum>("momentum_component")),
90  _sup_vel_provided(isParamValid(NS::superficial_velocity)),
91  _pressure_provided(isParamValid(NS::pressure)),
92  _T_fluid_provided(isParamValid(NS::T_fluid)),
93  _sup_vel_function(_sup_vel_provided ? &getFunction(NS::superficial_velocity) : nullptr),
94  _pressure_function(_pressure_provided ? &getFunction(NS::pressure) : nullptr),
95  _T_fluid_function(_T_fluid_provided ? &getFunction(NS::T_fluid) : nullptr),
96  _scalar_elem(_u),
97  _scalar_neighbor(_u_neighbor),
98  _grad_scalar_elem((_eqn == "scalar") ? &_var.adGradSln() : nullptr),
99  _grad_scalar_neighbor((_eqn == "scalar") ? &_var.adGradSlnNeighbor() : nullptr),
100  _scalar_function_provided(isParamValid("scalar")),
101  _scalar_function(_scalar_function_provided ? &getFunction("scalar") : nullptr),
102  _velocity_function_includes_rho(getParam<bool>("velocity_function_includes_rho")),
103  _mfr_pp(
104  isParamValid("mfr_postprocessor")
105  ? &const_cast<MfrPostprocessor &>(getUserObject<MfrPostprocessor>("mfr_postprocessor"))
106  : nullptr)
107 {
108  if ((_eqn == "momentum") && !isParamValid("momentum_component"))
109  paramError("eqn",
110  "If 'momentum' is specified for 'eqn', then you must provide a parameter "
111  "value for 'momentum_component'");
112  if ((_eqn != "momentum") && isParamValid("momentum_component"))
113  paramError("momentum_component",
114  "'momentum_component' should not be specified when the 'eqn' is not 'momentum'");
115 }
116 
117 ADReal
119 {
120  const auto ft = _face_info->faceType(std::make_pair(_var.number(), _var.sys().number()));
121  const bool out_of_elem = (ft == FaceInfo::VarFaceNeighbors::ELEM);
122  const auto normal = out_of_elem ? _face_info->normal() : Point(-_face_info->normal());
123 
124  const auto & sup_vel_x_interior = out_of_elem ? _sup_vel_x_elem[_qp] : _sup_vel_x_neighbor[_qp];
125  const auto & sup_vel_y_interior = out_of_elem ? _sup_vel_y_elem[_qp] : _sup_vel_y_neighbor[_qp];
126  const auto & sup_vel_z_interior = out_of_elem ? _sup_vel_z_elem[_qp] : _sup_vel_z_neighbor[_qp];
127  const auto & pressure_interior = out_of_elem ? _pressure_elem[_qp] : _pressure_neighbor[_qp];
128  const auto & T_fluid_interior = out_of_elem ? _T_fluid_elem[_qp] : _T_fluid_neighbor[_qp];
129 
130  const auto & grad_sup_vel_x_interior =
132  const auto & grad_sup_vel_y_interior =
134  const auto & grad_sup_vel_z_interior =
136  const auto & grad_pressure_interior =
138  const auto & grad_T_fluid_interior =
140  const auto & interior_centroid =
141  out_of_elem ? _face_info->elemCentroid() : _face_info->neighborCentroid();
142  const auto dCf = _face_info->faceCentroid() - interior_centroid;
143  const auto eps_interior = out_of_elem ? _eps_elem[_qp] : _eps_neighbor[_qp];
144 
145  const auto pressure_boundary =
147  : pressure_interior + grad_pressure_interior * dCf;
148  const auto T_fluid_boundary =
150  : T_fluid_interior + grad_T_fluid_interior * dCf;
151  const auto rho_boundary = _fluid.rho_from_p_T(pressure_boundary, T_fluid_boundary);
152 
153  ADReal sup_vel_x_boundary;
154  if (_sup_vel_provided)
155  {
156  sup_vel_x_boundary = _sup_vel_function->vectorValue(_t, _face_info->faceCentroid())(0);
158  sup_vel_x_boundary /= rho_boundary;
159  }
160  else
161  sup_vel_x_boundary = sup_vel_x_interior + grad_sup_vel_x_interior * dCf;
162 
163  ADReal sup_vel_y_boundary = 0;
164  if (_dim >= 2)
165  {
166  if (_sup_vel_provided)
167  {
168  sup_vel_y_boundary = _sup_vel_function->vectorValue(_t, _face_info->faceCentroid())(1);
170  sup_vel_y_boundary /= rho_boundary;
171  }
172  else
173  sup_vel_y_boundary = sup_vel_y_interior + grad_sup_vel_y_interior * dCf;
174  }
175 
176  ADReal sup_vel_z_boundary = 0;
177  if (_dim >= 3)
178  {
179  if (_sup_vel_provided)
180  {
181  sup_vel_z_boundary = _sup_vel_function->vectorValue(_t, _face_info->faceCentroid())(2);
183  sup_vel_z_boundary /= rho_boundary;
184  }
185  else
186  sup_vel_z_boundary = sup_vel_z_interior + grad_sup_vel_z_interior * dCf;
187  }
188 
189  const VectorValue<ADReal> sup_vel_boundary(
190  sup_vel_x_boundary, sup_vel_y_boundary, sup_vel_z_boundary);
191  const auto eps_boundary = eps_interior;
192  const auto u_boundary = sup_vel_boundary / eps_boundary;
193  const auto e_boundary = _fluid.e_from_p_T(pressure_boundary, T_fluid_boundary);
194 
195  if (_eqn == "mass")
196  {
197  const ADReal mfr = rho_boundary * sup_vel_boundary * normal;
198  if (_mfr_pp)
199  _mfr_pp->setMfr(_face_info, mfr.value(), false);
200  return mfr;
201  }
202  else if (_eqn == "momentum")
203  {
204  const auto rhou_boundary = u_boundary(_index) * rho_boundary;
205  return rhou_boundary * sup_vel_boundary * normal +
206  eps_boundary * pressure_boundary * normal(_index);
207  }
208  else if (_eqn == "energy")
209  {
210  const auto ht_boundary =
211  e_boundary + 0.5 * u_boundary * u_boundary + pressure_boundary / rho_boundary;
212  const auto rho_ht_boundary = rho_boundary * ht_boundary;
213  return rho_ht_boundary * sup_vel_boundary * normal;
214  }
215  else if (_eqn == "scalar")
216  {
217  const auto & scalar_interior = out_of_elem ? _scalar_elem[_qp] : _scalar_neighbor[_qp];
218  const auto & grad_scalar_interior =
219  out_of_elem ? (*_grad_scalar_elem)[_qp] : (*_grad_scalar_neighbor)[_qp];
220  const auto scalar_boundary =
222  : scalar_interior + grad_scalar_interior * dCf;
223  return rho_boundary * scalar_boundary * sup_vel_boundary * normal;
224  }
225  else
226  mooseError("Unrecognized equation type ", _eqn);
227 }
const ADMaterialProperty< RealVectorValue > & _grad_T_fluid_elem
static const std::string superficial_velocity
Definition: NS.h:53
const FaceInfo * _face_info
const MaterialProperty< Real > & _eps_elem
const unsigned int _dim
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_x_elem
const ADMaterialProperty< Real > & _sup_vel_z_neighbor
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
static InputParameters validParams()
unsigned int number() const
This postprocessor computes the volumetric flow rate through a boundary.
const Point & faceCentroid() const
const ADMaterialProperty< Real > & _T_fluid_neighbor
const MooseEnum _eqn
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_y_elem
static const std::string fluid
Definition: NS.h:87
const Function *const _pressure_function
const ADMaterialProperty< Real > & _sup_vel_y_elem
const ADMaterialProperty< Real > & _sup_vel_x_elem
const SinglePhaseFluidProperties & _fluid
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_z_elem
MooseVariableFV< Real > & _var
const Point & neighborCentroid() const
DualNumber< Real, DNDerivativeType, true > ADReal
const ADMaterialProperty< Real > & _pressure_elem
void addRequiredParam(const std::string &name, const std::string &doc_string)
const Function *const _sup_vel_function
const ADMaterialProperty< RealVectorValue > & _grad_T_fluid_neighbor
const Function *const _scalar_function
bool isParamValid(const std::string &name) const
const ADMaterialProperty< Real > & _sup_vel_x_neighbor
const unsigned int _qp
virtual ADReal computeQpResidual() override
const bool _pressure_provided
static const std::string porosity
Definition: NS.h:104
const ADMaterialProperty< RealVectorValue > & _grad_pressure_elem
const bool _sup_vel_provided
static const std::string T_fluid
Definition: NS.h:106
const Point & elemCentroid() const
static InputParameters validParams()
const ADMaterialProperty< Real > & _sup_vel_z_elem
static const std::string superficial_velocity_y
Definition: NS.h:51
Real & _t
const MaterialProperty< Real > & _eps_neighbor
Common class for single phase fluid properties.
const Point & normal() const
void paramError(const std::string &param, Args... args) const
unsigned int number() const
const ADMaterialProperty< Real > & _pressure_neighbor
std::string grad(const std::string &var)
Definition: NS.h:91
const Function *const _T_fluid_function
void setMfr(const FaceInfo *fi, Real mfr, bool includes_area=true)
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_z_neighbor
PCNSFVStrongBC(const InputParameters &params)
registerMooseObject("NavierStokesApp", PCNSFVStrongBC)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MfrPostprocessor *const _mfr_pp
static const std::string pressure
Definition: NS.h:56
virtual RealVectorValue vectorValue(Real t, const Point &p) const
void mooseError(Args &&... args) const
const ADMaterialProperty< RealVectorValue > & _grad_pressure_neighbor
const ADRealVectorValue & normal() const
void addClassDescription(const std::string &doc_string)
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_y_neighbor
const bool _velocity_function_includes_rho
const ADVariableValue & _scalar_elem
const ADVariableValue & _scalar_neighbor
virtual Real value(Real t, const Point &p) const
const unsigned int _index
const bool _scalar_function_provided
const ADMaterialProperty< Real > & _T_fluid_elem
static const std::string superficial_velocity_z
Definition: NS.h:52
const bool _T_fluid_provided
const ADMaterialProperty< Real > & _sup_vel_y_neighbor
VarFaceNeighbors faceType(const std::pair< unsigned int, unsigned int > &var_sys) const
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_x_neighbor
static const std::string superficial_velocity_x
Definition: NS.h:50