https://mooseframework.inl.gov
Loading...
Searching...
No Matches
WCNSFV2PMomentumAdvectionSlip.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
11#include "NS.h"
12#include "FVUtils.h"
14#include "SystemBase.h"
15#include "NSFVUtils.h"
16
18
21{
24 "Computes the slip velocity advection kernel for two-phase mixture model.");
25 params.addRequiredParam<MooseFunctorName>("u_slip", "The slip velocity in the x direction.");
26 params.addParam<MooseFunctorName>("v_slip", "The slip velocity in the y direction.");
27 params.addParam<MooseFunctorName>("w_slip", "The slip velocity in the z direction.");
28 params.addRequiredParam<MooseFunctorName>("rho_d", "Dispersed phase density.");
29 params.addParam<MooseFunctorName>("fd", 0.0, "Fraction dispersed phase.");
30 params.renameParam("fd", "fraction_dispersed", "");
31 params.setDocString(NS::density, "Main phase (not dispersed) density functor");
32
33 return params;
34}
35
37 : INSFVMomentumAdvection(params),
38 _rho_d(getFunctor<ADReal>("rho_d")),
39 _dim(_subproblem.mesh().dimension()),
40 _u_slip(getFunctor<ADReal>("u_slip")),
41 _v_slip(isParamValid("v_slip") ? &getFunctor<ADReal>("v_slip") : nullptr),
42 _w_slip(isParamValid("w_slip") ? &getFunctor<ADReal>("w_slip") : nullptr),
43 _fd(getFunctor<ADReal>("fd"))
44{
45 if (_dim >= 2 && !_v_slip)
46 mooseError("In two or more dimensions, the v_slip velocity must be supplied using the 'v_slip' "
47 "parameter");
48 if (_dim >= 3 && !_w_slip)
50 "In three dimensions, the w_slip velocity must be supplied using the 'w_slip' parameter");
51}
52
53void
55{
56 mooseAssert(!skipForBoundary(fi),
57 "We shouldn't get in here if we're supposed to skip for a boundary");
58
59 constexpr Real offset = 1e-15;
60 _face_info = &fi;
61 _normal = fi.normal();
62 _face_type = fi.faceType(std::make_pair(_var.number(), _var.sys().number()));
63 const auto state = determineState();
64
65 using namespace Moose::FV;
66
67 const bool correct_skewness = _advected_interp_method == InterpMethod::SkewCorrectedAverage;
68 const bool on_boundary = onBoundary(fi);
69
70 _elem_residual = 0, _neighbor_residual = 0, _ae = 0, _an = 0;
71
72 Moose::FaceArg face_arg;
73 if (on_boundary)
74 face_arg = singleSidedFaceArg();
75 else
76 face_arg = Moose::FaceArg{
77 &fi, Moose::FV::LimiterType::CentralDifference, true, false, nullptr, nullptr};
78
79 ADRealVectorValue u_slip_vel_vec;
80 if (_dim == 1)
81 u_slip_vel_vec(0) = _u_slip(face_arg, state);
82 if (_dim == 2)
83 u_slip_vel_vec = ADRealVectorValue(_u_slip(face_arg, state), (*_v_slip)(face_arg, state), 0.0);
84 if (_dim == 3)
85 u_slip_vel_vec = ADRealVectorValue(
86 _u_slip(face_arg, state), (*_v_slip)(face_arg, state), (*_w_slip)(face_arg, state));
87
88 const auto rho_mix = _rho(face_arg, state) +
89 (_rho_d(face_arg, state) - _rho(face_arg, state)) * _fd(face_arg, state);
90
91 const auto vdotn = _normal * u_slip_vel_vec;
92
93 if (on_boundary)
94 {
95 const auto ssf = singleSidedFaceArg();
96 const Elem * const sided_elem = ssf.face_side;
97 const auto dof_number = sided_elem->dof_number(_sys.number(), _var.number(), 0);
98 const auto rho_face = rho_mix;
99 const auto eps_face = epsilon()(ssf, state);
100 const auto u_face = _var(ssf, state);
101 const Real d_u_face_d_dof = u_face.derivatives()[dof_number];
102 const auto coeff = vdotn * rho_face / eps_face;
103
104 if (sided_elem == fi.elemPtr())
105 {
106 _ae = coeff * d_u_face_d_dof;
107 _elem_residual = coeff * u_face;
108 if (_approximate_as)
109 _ae = _cs / fi.elem().n_sides() * rho_face / eps_face;
110 }
111 else
112 {
113 _an = -coeff * d_u_face_d_dof;
114 _neighbor_residual = -coeff * u_face;
115 if (_approximate_as)
116 _an = _cs / fi.neighborPtr()->n_sides() * rho_face / eps_face;
117 }
118 }
119 else // we are an internal fluid flow face
120 {
121 const bool elem_is_upwind = MetaPhysicL::raw_value(u_slip_vel_vec) * _normal > 0;
122 const Moose::FaceArg advected_face_arg{&fi,
123 limiterType(_advected_interp_method),
124 elem_is_upwind,
125 correct_skewness,
126 nullptr,
127 nullptr};
128 if (const auto [is_jump, eps_elem_face, eps_neighbor_face] =
129 NS::isPorosityJumpFace(epsilon(), fi, state);
130 is_jump)
131 {
132 // For a weakly compressible formulation, the density should not depend on pressure and
133 // consequently the density should not be impacted by the pressure jump that occurs at a
134 // porosity jump. Consequently we will allow evaluation of the density using both upstream and
135 // downstream information
136 const auto rho_face =
137 _rho_d(advected_face_arg, state) - _rho(advected_face_arg, state) + offset;
138
139 // We set the + and - sides of the superficial velocity equal to the interpolated value
140 const auto & var_elem_face = u_slip_vel_vec(_index);
141 const auto & var_neighbor_face = u_slip_vel_vec(_index);
142
143 const auto elem_dof_number = fi.elem().dof_number(_sys.number(), _var.number(), 0);
144 const auto neighbor_dof_number = fi.neighbor().dof_number(_sys.number(), _var.number(), 0);
145
146 const auto d_var_elem_face_d_elem_dof = var_elem_face.derivatives()[elem_dof_number];
147 const auto d_var_neighbor_face_d_neighbor_dof =
148 var_neighbor_face.derivatives()[neighbor_dof_number];
149
150 // We allow a discontintuity in the advective momentum flux at the jump face. Mainly the
151 // advective flux is:
152 // elem side:
153 // rho * v_superficial / eps_elem * v_superficial = rho * v_interstitial_elem * v_superficial
154 // neighbor side:
155 // rho * v_superficial / eps_neigh * v_superficial = rho * v_interstitial_neigh *
156 // v_superficial
157 const auto elem_coeff = vdotn * rho_face / eps_elem_face;
158 const auto neighbor_coeff = vdotn * rho_face / eps_neighbor_face;
159 _ae = elem_coeff * d_var_elem_face_d_elem_dof;
160 _elem_residual = elem_coeff * var_elem_face;
161 _an = -neighbor_coeff * d_var_neighbor_face_d_neighbor_dof;
162 _neighbor_residual = -neighbor_coeff * var_neighbor_face;
163 if (_approximate_as)
164 {
165 _ae = _cs / fi.elem().n_sides() * rho_face / eps_elem_face;
166 _an = _cs / fi.neighborPtr()->n_sides() * rho_face / eps_elem_face;
167 }
168 }
169 else
170 {
171 const auto [interp_coeffs, advected] =
172 interpCoeffsAndAdvected(*_rho_u, advected_face_arg, state);
173
174 const auto elem_arg = elemArg();
175 const auto neighbor_arg = neighborArg();
176
177 const auto rho_elem = _rho_d(elem_arg, state) - _rho(elem_arg, state) + offset;
178 const auto rho_neighbor = _rho_d(neighbor_arg, state) - _rho(neighbor_arg, state) + offset;
179 const auto eps_elem = epsilon()(elem_arg, state),
180 eps_neighbor = epsilon()(neighbor_arg, state);
181 const auto var_elem = advected.first / rho_elem * eps_elem,
182 var_neighbor = advected.second / rho_neighbor * eps_neighbor;
183
184 _ae = vdotn * rho_elem / eps_elem * interp_coeffs.first;
185 // Minus sign because we apply a minus sign to the residual in computeResidual
186 _an = -vdotn * rho_neighbor / eps_neighbor * interp_coeffs.second;
187
188 _elem_residual = _ae * var_elem - _an * var_neighbor;
190
191 if (_approximate_as)
192 {
193 _ae = _cs / fi.elem().n_sides() * rho_elem / eps_elem;
194 _an = _cs / fi.neighborPtr()->n_sides() * rho_neighbor / eps_neighbor;
195 }
196 }
197 }
198
199 _ae *= fi.faceArea() * fi.faceCoord();
200 _an *= fi.faceArea() * fi.faceCoord();
201 _elem_residual *= fi.faceArea() * fi.faceCoord();
203}
DualNumber< Real, DNDerivativeType, true > ADReal
registerMooseObject("NavierStokesApp", WCNSFV2PMomentumAdvectionSlip)
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
const Point & normal() const
VarFaceNeighbors faceType(const std::pair< unsigned int, unsigned int > &var_sys) const
const Elem & elem() const
const Elem * neighborPtr() const
Real faceArea() const
Real & faceCoord()
const Elem * elemPtr() const
const Elem & neighbor() const
bool skipForBoundary(const FaceInfo &fi) const override
Moose::FV::InterpMethod _advected_interp_method
The interpolation method to use for the advected quantity.
An advection kernel that implements interpolation schemes specific to Navier-Stokes flow physics.
const Real _cs
Characteristic speed.
ADReal _an
The a coefficient for the neighbor.
ADReal _elem_residual
The element residual.
std::unique_ptr< PiecewiseByBlockLambdaFunctor< ADReal > > _rho_u
Our local momentum functor.
static InputParameters validParams()
const Moose::Functor< ADReal > & _rho
Density.
virtual const Moose::FunctorBase< ADReal > & epsilon() const
A virtual method that allows us to reuse all the code from free-flow for porous.
const bool _approximate_as
Whether to approximately calculate the 'a' coefficients.
ADReal _neighbor_residual
The neighbor residual.
ADReal _ae
The a coefficient for the element.
const unsigned int _index
index x|y|z
void renameParam(const std::string &old_name, const std::string &new_name, const std::string &new_docstring)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void setDocString(const std::string &name, const std::string &doc)
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)
void mooseError(Args &&... args) const
SystemBase & sys()
unsigned int number() const
SystemBase & _sys
unsigned int number() const
Moose::StateArg determineState() const
Adds momentum kernel coming from the slip velocity in two-phase mixture model.
const Moose::Functor< ADReal > & _rho_d
Dispersed phase density.
WCNSFV2PMomentumAdvectionSlip(const InputParameters &params)
const Moose::Functor< ADReal > *const _v_slip
slip velocity in direction y
virtual void computeResidualsAndAData(const FaceInfo &fi) override
Helper method that computes the 'a' coefficients and AD residuals.
const Moose::Functor< ADReal > & _u_slip
slip velocity in direction x
const Moose::Functor< ADReal > *const _w_slip
slip velocity in direction z
const unsigned int _dim
the dimension of the simulation
const Moose::Functor< ADReal > & _fd
Particle diameter in the dispersed phase.
MeshBase & mesh
auto raw_value(const Eigen::Map< T > &in)
static const std::string density
Definition NS.h:34
std::tuple< bool, T, T > isPorosityJumpFace(const Moose::FunctorBase< T > &porosity, const FaceInfo &fi, const Moose::StateArg &time)
Checks to see whether the porosity value jumps from one side to the other of the provided face.
Definition NSFVUtils.C:119