https://mooseframework.inl.gov
PINSFVMomentumDiffusion.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"
14 #include "SystemBase.h"
15 
17 
20 {
22  params.addClassDescription(
23  "Viscous diffusion term, div(mu eps grad(u_d / eps)), in the porous media "
24  "incompressible Navier-Stokes momentum equation.");
25  params.addRequiredParam<MooseFunctorName>(NS::porosity, "Porosity auxiliary variable");
26  return params;
27 }
28 
30  : INSFVMomentumDiffusion(params), _eps(getFunctor<ADReal>(NS::porosity))
31 {
32  if (!dynamic_cast<PINSFVSuperficialVelocityVariable *>(&_var))
33  mooseError("PINSFVMomentumDiffusion may only be used with a superficial velocity "
34  "variable, of variable type PINSFVSuperficialVelocityVariable.");
35 }
36 
37 ADReal
39 {
40  using namespace Moose::FV;
41 
42  const bool has_elem = (_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
44  const bool has_neighbor = (_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR ||
46 
47  const auto elem_face = elemArg();
48  const auto neighbor_face = neighborArg();
49  const auto state = determineState();
50 
51  // Compute the diffusion driven by the velocity gradient
52  // Interpolate viscosity divided by porosity on the face
53  ADReal mu_face;
54 
55  const auto mu_elem = has_elem ? _mu(elem_face, state) : _mu(neighbor_face, state);
56  const auto eps_elem = has_elem ? _eps(elem_face, state) : _eps(neighbor_face, state);
57 
58  ADReal mu_neighbor;
59  ADReal eps_neighbor;
60  if (onBoundary(*_face_info))
61  mu_face = _mu(singleSidedFaceArg(), state);
62  else
63  {
64  mu_neighbor = has_elem ? _mu(neighbor_face, state) : _mu(elem_face, state);
65  eps_neighbor = has_neighbor ? _eps(neighbor_face, state) : _eps(elem_face, state);
66  interpolate(Moose::FV::InterpMethod::Average, mu_face, mu_elem, mu_neighbor, *_face_info, true);
67  }
68 
69  // Compute face superficial velocity gradient
70  auto dudn = _var.gradient(makeCDFace(*_face_info), state) * _face_info->normal();
71 
72  if (populate_a_coeffs)
73  {
74  if (has_elem)
75  {
76  const auto dof_number = _face_info->elem().dof_number(_sys.number(), _var.number(), 0);
77  // A gradient is a linear combination of degrees of freedom so it's safe to straight-up index
78  // into the derivatives vector at the dof we care about
79  _ae = dudn.derivatives()[dof_number];
80  _ae *= -mu_face;
81  }
82  if (has_neighbor)
83  {
84  const auto dof_number = _face_info->neighbor().dof_number(_sys.number(), _var.number(), 0);
85  _an = dudn.derivatives()[dof_number];
86  _an *= mu_face;
87  }
88  }
89 
90  // First term of residual
91  ADReal residual = mu_face * dudn;
92 
93  // Get the face porosity gradient separately
94  const auto & grad_eps_face =
95  (has_elem && has_neighbor)
96  ? MetaPhysicL::raw_value(_eps.gradient(makeCDFace(*_face_info), state))
97  : MetaPhysicL::raw_value(_eps.gradient(
98  makeElemArg(has_elem ? &_face_info->elem() : _face_info->neighborPtr()), state));
99 
100  // Interpolate to get the face value
101  ADReal coeff_face;
102  // At this point, we already computed mu_elem/eps_elem by knowing which element owns the
103  // face, so it is enough to switch between the variable evaluation here
104  const auto coeff_one_side =
105  mu_elem / eps_elem * (has_elem ? _var(elem_face, state) : _var(neighbor_face, state));
106  if (onBoundary(*_face_info))
107  coeff_face = coeff_one_side;
108  else
109  {
110  mooseAssert(has_elem, "We should be defined on the element side if we're not on a boundary");
111  const auto coeff_neighbor = mu_neighbor / eps_neighbor *
112  (has_elem ? _var(neighbor_face, state) : _var(elem_face, state));
114  coeff_face,
115  coeff_one_side,
116  coeff_neighbor,
117  *_face_info,
118  true);
119  }
120 
121  residual -= coeff_face * grad_eps_face * _normal;
122 
123  return -residual;
124 }
ADReal _ae
The a coefficient for the element.
ADReal _an
The a coefficient for the neighbor.
Moose::ElemArg elemArg(bool correct_skewness=false) const
unsigned int number() const
const Elem & elem() const
const FaceInfo * _face_info
Moose::StateArg determineState() const
auto raw_value(const Eigen::Map< T > &in)
RealVectorValue _normal
DualNumber< Real, DNDerivativeType, true > ADReal
const Moose::Functor< ADReal > & _eps
the porosity
SystemBase & _sys
Moose::ElemArg makeElemArg(const Elem *elem, bool correct_skewnewss=false) const
static const std::string porosity
Definition: NS.h:104
bool onBoundary(const FaceInfo &fi) const
A flux kernel for diffusion of momentum in porous media across cell faces.
const Elem * neighborPtr() const
PINSFVMomentumDiffusion(const InputParameters &params)
const Moose::Functor< ADReal > & _mu
The dynamic viscosity.
const Elem & neighbor() const
const Point & normal() const
unsigned int number() const
virtual ADReal computeStrongResidual(const bool populate_a_coeffs) override
Routine to compute this object&#39;s strong residual (e.g.
FaceInfo::VarFaceNeighbors _face_type
Moose::ElemArg neighborArg(bool correct_skewness=false) const
static InputParameters validParams()
GradientType gradient(const ElemArg &elem, const StateArg &state) const
static InputParameters validParams()
void mooseError(Args &&... args) const
Moose::FaceArg singleSidedFaceArg(const FaceInfo *fi=nullptr, Moose::FV::LimiterType limiter_type=Moose::FV::LimiterType::CentralDifference, bool correct_skewness=false, const Moose::StateArg *state_limiter=nullptr) const
MooseVariableFV< Real > & _var
Moose::FaceArg makeCDFace(const FaceInfo &fi, const bool correct_skewness=false) const
registerMooseObject("NavierStokesApp", PINSFVMomentumDiffusion)
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)