23 params.addParam<Real>(
24 "characteristic_speed",
25 "The characteristic speed. For porous medium simulations, this characteristic speed should "
26 "correspond to the superficial velocity, not the interstitial.");
30std::vector<std::string>
33 return {
"characteristic_speed"};
50 _rho(getFunctor<
ADReal>(
NS::density)),
51 _approximate_as(isParamValid(
"characteristic_speed")),
52 _cs(_approximate_as ? getParam<Real>(
"characteristic_speed") : 0)
61 _rho_u = std::make_unique<PiecewiseByBlockLambdaFunctor<ADReal>>(
63 [
this](
const auto & r,
const auto & t) ->
ADReal
80 "We shouldn't get in here if we're supposed to skip for a boundary");
95 const auto vdotn =
_normal * v_face;
100 const Elem *
const sided_elem = ssf.face_side;
102 const auto rho_face =
_rho(ssf, state);
103 const auto eps_face =
epsilon()(ssf, state);
104 const auto u_face =
_var(ssf, state);
105 const Real d_u_face_d_dof = u_face.derivatives()[dof_number];
106 const auto coeff = vdotn * rho_face / eps_face;
108 if (sided_elem == fi.
elemPtr())
110 _ae = coeff * d_u_face_d_dof;
113 _ae =
_cs / fi.
elem().n_sides() * rho_face / eps_face;
117 _an = -coeff * d_u_face_d_dof;
135 if (
const auto [is_jump, eps_elem_face, eps_neighbor_face] =
143 const auto rho_face =
_rho(advected_face_arg, state);
146 const auto & var_elem_face = v_face(
_index);
147 const auto & var_neighbor_face = v_face(
_index);
152 const auto d_var_elem_face_d_elem_dof = var_elem_face.derivatives()[elem_dof_number];
153 const auto d_var_neighbor_face_d_neighbor_dof =
154 var_neighbor_face.derivatives()[neighbor_dof_number];
163 const auto elem_coeff = vdotn * rho_face / eps_elem_face;
164 const auto neighbor_coeff = vdotn * rho_face / eps_neighbor_face;
165 _ae = elem_coeff * d_var_elem_face_d_elem_dof;
167 _an = -neighbor_coeff * d_var_neighbor_face_d_neighbor_dof;
171 _ae =
_cs / fi.
elem().n_sides() * rho_face / eps_elem_face;
177 const auto [interp_coeffs, advected] =
178 interpCoeffsAndAdvected(*
_rho_u, advected_face_arg, state);
180 const auto elem_arg =
elemArg();
183 const auto rho_elem =
_rho(elem_arg, state), rho_neighbor =
_rho(neighbor_arg, state);
184 const auto eps_elem =
epsilon()(elem_arg, state),
185 eps_neighbor =
epsilon()(neighbor_arg, state);
186 const auto var_elem = advected.first / rho_elem * eps_elem,
187 var_neighbor = advected.second / rho_neighbor * eps_neighbor;
189 _ae = vdotn * rho_elem / eps_elem * interp_coeffs.first;
191 _an = -vdotn * rho_neighbor / eps_neighbor * interp_coeffs.second;
198 _ae =
_cs / fi.
elem().n_sides() * rho_elem / eps_elem;
218 if (
_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
219 _face_type == FaceInfo::VarFaceNeighbors::BOTH)
227 if (
_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR ||
228 _face_type == FaceInfo::VarFaceNeighbors::BOTH)
245 if (
_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
246 _face_type == FaceInfo::VarFaceNeighbors::BOTH)
248 mooseAssert(
_var.
dofIndices().size() == 1,
"We're currently built to use CONSTANT MONOMIALS");
256 if (
_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR ||
257 _face_type == FaceInfo::VarFaceNeighbors::BOTH)
259 mooseAssert((
_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR) ==
261 "If the variable is only defined on the neighbor hand side of the face, then that "
262 "means it should have no dof indices on the elem element. Conversely if "
263 "the variable is defined on both sides of the face, then it should have a non-zero "
264 "number of degrees of freedom on the elem element");
267 "We're currently built to use CONSTANT MONOMIALS");
288 if (
_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
289 _face_type == FaceInfo::VarFaceNeighbors::BOTH)
291 if (
_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR ||
292 _face_type == FaceInfo::VarFaceNeighbors::BOTH)
DualNumber< Real, DNDerivativeType, true > ADReal
registerMooseObject("NavierStokesApp", INSFVMomentumAdvection)
const ExecFlagType EXEC_ALWAYS
virtual const std::set< SubdomainID > & blockIDs() const
Moose::ElemArg neighborArg(bool correct_skewness=false) const
Moose::ElemArg elemArg(bool correct_skewness=false) const
void computeJacobian() override
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
void computeResidual() override
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
const Elem * elemPtr() const
const Elem & neighbor() const
An advection kernel that implements interpolation schemes specific to Navier-Stokes flow physics.
bool skipForBoundary(const FaceInfo &fi) const override
ADRealVectorValue velocity() const
Moose::FV::InterpMethod _velocity_interp_method
The interpolation method to use for the velocity.
void initialSetup() override
Moose::FV::InterpMethod _advected_interp_method
The interpolation method to use for the advected quantity.
static InputParameters validParams()
An advection kernel that implements interpolation schemes specific to Navier-Stokes flow physics.
void gatherRCData(const Elem &) override final
Should be a non-empty implementation if the residual object is a FVElementalKernel and introduces res...
const Real _cs
Characteristic speed.
ADReal _an
The a coefficient for the neighbor.
ADReal _elem_residual
The element residual.
static InputParameters uniqueParams()
Parameters of this object that should be added to the NSFV action that are unique to this object.
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.
virtual void computeResidualsAndAData(const FaceInfo &fi)
Helper method that computes the 'a' coefficients and AD residuals.
virtual ADReal computeQpResidual() override final
void initialSetup() override
INSFVMomentumAdvection(const InputParameters ¶ms)
const bool _approximate_as
Whether to approximately calculate the 'a' coefficients.
static std::vector< std::string > listOfCommonParams()
ADReal _neighbor_residual
The neighbor residual.
ADReal _ae
The a coefficient for the element.
All objects that contribute to pressure-based (e.g.
const unsigned int _index
index x|y|z
static InputParameters validParams()
RhieChowInterpolatorBase & _rc_uo
The Rhie Chow user object that is responsible for generating face velocities for advection terms.
void mooseError(Args &&... args) const
void scalingFactor(const std::vector< Real > &factor)
unsigned int number() const
virtual const std::vector< dof_id_type > & dofIndices() const final
virtual const std::vector< dof_id_type > & dofIndicesNeighbor() const final
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.
virtual bool isTransient() const=0
unsigned int number() const
void accumulateTaggedLocalResidual()
void addResidualsAndJacobian(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
void prepareVectorTagNeighbor(Assembly &assembly, unsigned int ivar)
void prepareVectorTag(Assembly &assembly, unsigned int ivar)
DenseVector< Number > _local_re
Moose::StateArg determineState() const
static const std::string density
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.