https://mooseframework.inl.gov
PINSFVMomentumFrictionCorrection.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 
12 #include "NS.h"
13 #include "SystemBase.h"
14 
16 
19 {
20  auto params = INSFVFluxKernel::validParams();
21  params.addClassDescription(
22  "Computes a correction term to avoid oscillations from average pressure interpolation in "
23  "regions of high changes in friction coefficients.");
24  params.addParam<MooseFunctorName>("Darcy_name", "Name of the Darcy coefficients property.");
25  params.addParam<MooseFunctorName>("Forchheimer_name",
26  "Name of the Forchheimer coefficients property.");
27  params.addRequiredParam<MooseFunctorName>(NS::density, "The density.");
28  params.addParam<MooseFunctorName>(
29  NS::speed,
30  "The norm of the interstitial velocity. This is required for Forchheimer calculations");
31  params.addParam<MooseFunctorName>(NS::mu, NS::mu, "The dynamic viscosity");
32  params.addRangeCheckedParam<Real>("consistent_scaling",
33  1,
34  "consistent_scaling >= 0",
35  "Smoothing scaling parameter to control "
36  "collocated mesh oscillations");
37  return params;
38 }
39 
41  : INSFVFluxKernel(params),
42  _D(isParamValid("Darcy_name") ? &getFunctor<ADRealVectorValue>("Darcy_name") : nullptr),
43  _F(isParamValid("Forchheimer_name") ? &getFunctor<ADRealVectorValue>("Forchheimer_name")
44  : nullptr),
45  _use_Darcy_friction_model(isParamValid("Darcy_name")),
46  _use_Forchheimer_friction_model(isParamValid("Forchheimer_name")),
47  _rho(getFunctor<ADReal>(NS::density)),
48  _mu(getFunctor<ADReal>(NS::mu)),
49  _speed(isParamValid(NS::speed) ? &getFunctor<ADReal>(NS::speed) : nullptr),
50  _consistent_scaling(getParam<Real>("consistent_scaling"))
51 {
53  mooseError("At least one friction model needs to be specified.");
54 
56  mooseError("If using a Forchheimer friction model, then the '",
57  NS::speed,
58  "' parameter must be provided");
59 }
60 
61 void
63 {
64  if (skipForBoundary(fi))
65  return;
66 
67  _face_info = &fi;
68  _normal = fi.normal();
69  _face_type = fi.faceType(std::make_pair(_var.number(), _var.sys().number()));
70 
71  using namespace Moose::FV;
72 
73  const auto elem_face = elemArg();
74  const auto neighbor_face = neighborArg();
75  const auto state = determineState();
76 
77  Point _face_centroid = _face_info->faceCentroid();
78  Point _elem_centroid = _face_info->elemCentroid();
79 
80  ADReal friction_term_elem = 0;
81  ADReal friction_term_neighbor = 0;
82 
83  ADReal diff_face;
84 
85  // If we are on an internal face for the variable, we interpolate the friction terms
86  // to the face using the cell values
88  {
90  {
91  friction_term_elem += (*_D)(elem_face, state)(_index)*_mu(elem_face, state);
92  friction_term_neighbor += (*_D)(neighbor_face, state)(_index)*_mu(neighbor_face, state);
93  }
95  {
96  friction_term_elem +=
97  (*_F)(elem_face, state)(_index)*_rho(elem_face, state) / 2 * (*_speed)(elem_face, state);
98  friction_term_neighbor += (*_F)(neighbor_face, state)(_index)*_rho(neighbor_face, state) / 2 *
99  (*_speed)(neighbor_face, state);
100  }
101 
102  Point _neighbor_centroid = _face_info->neighborCentroid();
103 
104  Real geometric_factor = _consistent_scaling * (_neighbor_centroid - _face_centroid).norm() *
105  (_elem_centroid - _face_centroid).norm();
106 
107  // Compute the diffusion driven by the velocity gradient
108  // Interpolate viscosity divided by porosity on the face
110  diff_face,
111  friction_term_elem * geometric_factor,
112  friction_term_neighbor * geometric_factor,
113  *_face_info,
114  true);
115  }
116  // If not, we use the extrapolated values of the functors on the face
117  else
118  {
119  const auto face =
122  friction_term_elem += (*_D)(face, state)(_index)*_mu(face, state);
124  friction_term_elem +=
125  (*_F)(face, state)(_index)*_rho(face, state) / 2 * (*_speed)(face, state);
126 
127  Real geometric_factor =
128  _consistent_scaling * std::pow((_elem_centroid - _face_centroid).norm(), 2);
129 
130  diff_face = friction_term_elem * geometric_factor;
131  }
132 
133  // Compute face superficial velocity gradient
134  auto dudn = _var.gradient(makeCDFace(*_face_info), state) * _face_info->normal();
135 
138  {
139  const auto dof_number = _face_info->elem().dof_number(_sys.number(), _var.number(), 0);
140  // A gradient is a linear combination of degrees of freedom so it's safe to straight-up index
141  // into the derivatives vector at the dof we care about
142  ADReal ae = dudn.derivatives()[dof_number];
143  ae *= -diff_face;
144  _rc_uo.addToA(&fi.elem(), _index, ae * (fi.faceArea() * fi.faceCoord()));
145  }
148  {
149  const auto dof_number = _face_info->neighbor().dof_number(_sys.number(), _var.number(), 0);
150  ADReal an = dudn.derivatives()[dof_number];
151  an *= diff_face;
152  _rc_uo.addToA(fi.neighborPtr(), _index, an * (fi.faceArea() * fi.faceCoord()));
153  }
154 
155  const auto strong_resid = -diff_face * dudn;
156 
157  addResidualAndJacobian(strong_resid * (fi.faceArea() * fi.faceCoord()));
158 }
static const std::string speed
Definition: NS.h:143
A flux kernel that momentum residual objects that add non-advection flux terms, or more specifically ...
Moose::ElemArg elemArg(bool correct_skewness=false) const
unsigned int number() const
const Moose::Functor< ADReal > & _mu
Dynamic viscosity as a functor.
const Elem & elem() const
const FaceInfo * _face_info
Moose::StateArg determineState() const
const Point & faceCentroid() const
const unsigned int _index
index x|y|z
static const std::string density
Definition: NS.h:33
Real & faceCoord()
const Moose::Functor< ADReal > & _rho
Density as a functor.
const Point & neighborCentroid() const
RealVectorValue _normal
Real faceArea() const
PINSFVMomentumFrictionCorrection(const InputParameters &params)
RhieChowInterpolatorBase & _rc_uo
The Rhie Chow user object that is responsible for generating face velocities for advection terms...
SystemBase & _sys
virtual bool skipForBoundary(const FaceInfo &fi) const
bool isInternalFace(const FaceInfo &) const
LimiterType limiterType(InterpMethod interp_method)
const Elem * neighborPtr() const
const Point & elemCentroid() const
static const std::string mu
Definition: NS.h:123
const Elem & neighbor() const
const Point & normal() const
unsigned int number() const
auto norm(const T &a) -> decltype(std::abs(a))
FaceInfo::VarFaceNeighbors _face_type
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addResidualAndJacobian(const ADReal &residual)
Process into either the system residual or Jacobian.
virtual void addToA(const libMesh::Elem *elem, unsigned int component, const ADReal &value)=0
API for momentum residual objects that have on-diagonals for velocity call.
Moose::ElemArg neighborArg(bool correct_skewness=false) const
GradientType gradient(const ElemArg &elem, const StateArg &state) const
static InputParameters validParams()
void mooseError(Args &&... args) const
const bool _use_Darcy_friction_model
Booleans to select the right models.
Real _consistent_scaling
Parameter for scaling the consistent pressure interpolation.
MooseVariableFV< Real > & _var
const Moose::Functor< ADReal > *const _speed
Speed (norm of the interstitial velocity) as a functor.
Moose::FaceArg makeCDFace(const FaceInfo &fi, const bool correct_skewness=false) const
registerMooseObject("NavierStokesApp", PINSFVMomentumFrictionCorrection)
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
MooseUnits pow(const MooseUnits &, int)
void gatherRCData(const FaceInfo &fi) override final
Should be a non-empty implementation if the residual object is a FVFluxKernel and introduces residual...
Moose::FaceArg makeFace(const FaceInfo &fi, const Moose::FV::LimiterType limiter_type, const bool elem_is_upwind, const bool correct_skewness=false, const Moose::StateArg *state_limiter=nullptr) const
VarFaceNeighbors faceType(const std::pair< unsigned int, unsigned int > &var_sys) const