https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
39{
40 using namespace Moose::FV;
41
42 const bool has_elem = (_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
43 _face_type == FaceInfo::VarFaceNeighbors::BOTH);
44 const bool has_neighbor = (_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR ||
45 _face_type == FaceInfo::VarFaceNeighbors::BOTH);
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;
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)
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));
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));
113 interpolate(Moose::FV::InterpMethod::Average,
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}
DualNumber< Real, DNDerivativeType, true > ADReal
registerMooseObject("NavierStokesApp", PINSFVMomentumDiffusion)
Moose::ElemArg neighborArg(bool correct_skewness=false) const
Moose::ElemArg elemArg(bool correct_skewness=false) const
RealVectorValue _normal
bool onBoundary(const FaceInfo &fi) const
MooseVariableFV< Real > & _var
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
const FaceInfo * _face_info
FaceInfo::VarFaceNeighbors _face_type
Moose::FaceArg makeCDFace(const FaceInfo &fi, const bool correct_skewness=false) const
const Point & normal() const
const Elem & elem() const
const Elem * neighborPtr() const
const Elem & neighbor() const
Moose::ElemArg makeElemArg(const Elem *elem, bool correct_skewnewss=false) const
ADReal _ae
The a coefficient for the element.
ADReal _an
The a coefficient for the neighbor.
static InputParameters validParams()
const Moose::Functor< ADReal > & _mu
The dynamic viscosity.
void mooseError(Args &&... args) const
unsigned int number() const
GradientType gradient(const ElemArg &elem, const StateArg &state) const
A flux kernel for diffusion of momentum in porous media across cell faces.
virtual ADReal computeStrongResidual(const bool populate_a_coeffs) override
Routine to compute this object's strong residual (e.g.
PINSFVMomentumDiffusion(const InputParameters &params)
const Moose::Functor< ADReal > & _eps
the porosity
static InputParameters validParams()
SystemBase & _sys
unsigned int number() const
Moose::StateArg determineState() const
auto raw_value(const Eigen::Map< T > &in)
static const std::string porosity
Definition NS.h:108