17#include "metaphysicl/raw_type.h"
18#include "libmesh/compare_types.h"
19#include "libmesh/elem.h"
95 const std::string & param_name);
115template <
typename T = Real>
119 const bool one_is_elem,
120 const T & face_flux = 0.0)
128 return std::make_pair(fi.
gC(), 1. - fi.
gC());
130 return std::make_pair(1. - fi.
gC(), fi.
gC());
135 if ((face_flux > 0) == one_is_elem)
136 return std::make_pair(1., 0.);
138 return std::make_pair(0., 1.);
142 mooseError(
"Unrecognized interpolation method");
151template <
typename T,
typename T2>
156 const bool one_is_elem,
161 "The selected interpolation function only works with average or skewness-corrected "
163 const auto coeffs =
interpCoeffs(interp_method, fi, one_is_elem);
164 return coeffs.first * value1 + coeffs.second * value2;
177template <
typename T1,
typename T2>
183 static_assert(std::is_same<typename MetaPhysicL::RawType<T1>::value_type,
184 typename MetaPhysicL::RawType<T2>::value_type>::value,
185 "The input values for harmonic interpolation need to have the same raw-value!");
195 if (value1 * value2 <= 0)
198 ") must be of the same sign for harmonic interpolation");
200 return 1.0 / (weight1 / value1 + weight2 / value2);
209 if (value1(i) * value2(i) <= 0)
210 mooseWarning(
"Component " + std::to_string(i) +
" of input values (" +
213 ") must be of the same sign for harmonic interpolation");
215 result(i) = 1.0 / (weight1 / value1(i) + weight2 / value2(i));
228 if (value1(i, j) * value2(i, j) <= 0)
229 mooseWarning(
"Component (" + std::to_string(i) +
"," + std::to_string(j) +
230 ") of input values (" +
233 ") must be of the same sign for harmonic interpolation");
235 result(i, j) = 1.0 / (weight1 / value1(i, j) + weight2 / value2(i, j));
244 static_assert(Moose::always_false<T1>,
245 "Harmonic interpolation is not implemented for the used type!");
258template <
typename T1,
typename T2>
263 const bool one_is_elem)
275template <
typename T,
typename T2,
typename T3>
279 const T3 & face_gradient,
281 const bool one_is_elem)
285 auto value = (coeffs.first * value1 + coeffs.second * value2) +
296template <
typename T,
typename T2,
typename T3>
303 const bool one_is_elem)
315 mooseError(
"unsupported interpolation method for interpolate() function");
323template <
typename T, FunctorEvaluationKind FEK = FunctorEvaluationKind::Value>
328 "Only Value and Dot evaluations currently supported");
330 "this interpolation method is meant for linear interpolations");
333 "We must have a non-null face_info in order to prepare our ElemFromFace tuples");
337 const auto elem_arg = face.
makeElem();
340 const auto elem_eval = functor.template genericEvaluate<FEK>(elem_arg, time);
341 const auto neighbor_eval = functor.template genericEvaluate<FEK>(neighbor_arg, time);
351 const auto surface_gradient = functor.template genericEvaluate<GFEK>(new_face, time);
354 elem_eval, neighbor_eval, surface_gradient, *face.
fi,
true);
363template <
typename T1,
366 template <
typename>
class Vector1,
367 template <
typename>
class Vector2>
370 Vector1<T1> & result,
371 const T2 & fi_elem_advected,
372 const T2 & fi_neighbor_advected,
373 const Vector2<T3> & fi_elem_advector,
374 const Vector2<T3> & fi_neighbor_advector,
381 fi_neighbor_advected * fi_neighbor_advector,
391 Real elem_coeff, neighbor_coeff;
392 if (face_advector * fi.
normal() > 0)
393 elem_coeff = 1, neighbor_coeff = 0;
395 elem_coeff = 0, neighbor_coeff = 1;
397 result = elem_coeff * fi_elem_advected * fi_elem_advector +
398 neighbor_coeff * fi_neighbor_advected * fi_neighbor_advector;
402 mooseError(
"unsupported interpolation method for FVFaceInterface::interpolate");
414template <
typename T,
typename T2,
typename T3,
typename Vector>
420 const Vector & advector,
422 const bool one_is_elem)
425 result = coeffs.first * value1 + coeffs.second * value2;
434 bool correct_skewness =
false);
459template <
typename Scalar,
typename Vector>
461rF(
const Scalar & phiC,
const Scalar & phiD,
const Vector & gradC,
const RealVectorValue & dCD)
463 const Scalar denom = phiD - phiC;
464 const Scalar grad_dot = gradC * dCD;
468 constexpr Real eps = 1e-10;
469 const Real denom_sign =
473 const Scalar safe = denom + denom_sign * eps;
474 return 2.0 * grad_dot / safe - 1.0;
491 const T & phi_upwind,
492 const T & phi_downwind,
495 const Real & max_value,
496 const Real & min_value,
498 const bool fi_elem_is_upwind)
501 const auto beta = limiter(phi_upwind,
505 fi_elem_is_upwind ? fi.
dCN() : Point(-fi.
dCN()),
511 const auto w_f = fi_elem_is_upwind ? fi.
gC() : (1. - fi.
gC());
513 const auto g = beta * (1. - w_f);
515 return std::make_pair(1. - g, g);
521template <
typename Scalar,
523 typename Enable =
typename std::enable_if<libMesh::ScalarTraits<Scalar>::value>::type>
526 const Scalar & phi_upwind,
527 const Scalar & phi_downwind,
528 const Vector *
const grad_phi_upwind,
530 const bool fi_elem_is_upwind)
538 std::numeric_limits<Real>::max(),
539 std::numeric_limits<Real>::min(),
542 return pr.first * phi_upwind + pr.second * phi_downwind;
548template <
typename Limiter,
typename T,
typename Tensor>
551 const TypeVector<T> & phi_upwind,
552 const TypeVector<T> & phi_downwind,
553 const Tensor *
const grad_phi_upwind,
555 const bool fi_elem_is_upwind)
557 mooseAssert(limiter.
constant() || grad_phi_upwind,
558 "Non-null gradient only supported for constant limiters.");
562 for (
const auto i : make_range(
unsigned(LIBMESH_DIM)))
568 interpolate(limiter, phi_upwind(i), phi_downwind(i), &gradient, fi, fi_elem_is_upwind);
572 limiter, phi_upwind(i), phi_downwind(i), gradient_example, fi, fi_elem_is_upwind);
599 const T & phi_upwind,
600 const T & phi_downwind,
601 const VectorValue<T> *
const grad_phi_upwind,
602 const VectorValue<T> *
const grad_phi_face,
603 const Real & max_value,
604 const Real & min_value,
611 const auto beta = limiter(phi_upwind,
623 const auto & cell_centroid =
629 delta_face = (*grad_phi_upwind) * (face_centroid - cell_centroid);
631 delta_face = (*grad_phi_face) * (face_centroid - cell_centroid);
634 return phi_upwind + beta * delta_face;
661 typename Enable =
typename std::enable_if<ScalarTraits<T>::value>::type>
666 Real max_value(std::numeric_limits<Real>::min()), min_value(std::numeric_limits<Real>::max());
669 for (
const auto neighbor : (*face.
fi).elem().neighbor_ptr_range())
672 if (neighbor ==
nullptr)
676 const ElemArg local_cell_arg = {neighbor,
false};
679 max_value = std::max(max_value, value);
680 min_value = std::min(min_value, value);
684 for (
const auto neighbor : (*face.
fi).neighbor().neighbor_ptr_range())
687 if (neighbor ==
nullptr)
691 const ElemArg local_cell_arg = {neighbor,
false};
694 max_value = std::max(max_value, value);
695 min_value = std::min(min_value, value);
699 return std::make_pair(max_value, min_value);
732 const unsigned int & component)
735 Real max_value(std::numeric_limits<Real>::min()), min_value(std::numeric_limits<Real>::max());
738 for (
const auto neighbor : (*face.
fi).elem().neighbor_ptr_range())
741 if (neighbor ==
nullptr)
746 const ElemArg local_cell_arg = {neighbor,
false};
748 max_value = std::max(max_value, value);
749 min_value = std::min(min_value, value);
753 for (
const auto neighbor : (*face.
fi).neighbor().neighbor_ptr_range())
756 if (neighbor ==
nullptr)
761 const ElemArg local_cell_arg = {neighbor,
false};
763 max_value = std::max(max_value, value);
764 min_value = std::min(min_value, value);
768 return std::make_pair(max_value, min_value);
801 typename Enable =
typename std::enable_if<libMesh::ScalarTraits<T>::value>::type>
802std::pair<std::pair<T, T>, std::pair<T, T>>
807 "Only Value and Dot evaluations currently supported");
812 static const GradientType zero(0);
814 mooseAssert(face.
fi,
"this must be non-null");
824 auto phi_upwind = functor.template genericEvaluate<FEK>(upwind_arg, time);
825 auto phi_downwind = functor.template genericEvaluate<FEK>(downwind_arg, time);
828 std::pair<T, T> interp_coeffs;
838 std::numeric_limits<Real>::max(),
839 std::numeric_limits<Real>::min(),
849 time_arg = &temp_state;
852 Real max_value(std::numeric_limits<Real>::min()), min_value(std::numeric_limits<Real>::max());
859 const auto grad_phi_upwind = functor.template genericEvaluate<GFEK>(upwind_arg, *time_arg);
860 const auto grad_phi_face = functor.template genericEvaluate<GFEK>(face, *time_arg);
876 return std::make_pair(std::move(interp_coeffs),
877 std::make_pair(std::move(phi_upwind), std::move(phi_downwind)));
879 return std::make_pair(
880 std::make_pair(std::move(interp_coeffs.second), std::move(interp_coeffs.first)),
881 std::make_pair(std::move(phi_downwind), std::move(phi_upwind)));
909 typename Enable =
typename std::enable_if<libMesh::ScalarTraits<T>::value>::type>
915 "Only Value and Dot evaluations currently supported");
920 return linearInterpolation<T, FEK>(functor, face, time);
926 const auto [interp_coeffs, advected] = interpCoeffsAndAdvected<T, FEK>(functor, face, time);
928 return interp_coeffs.first * advected.first + interp_coeffs.second * advected.second;
935 static const GradientType zero(0);
936 const auto & limiter =
942 const auto & phi_upwind = functor.template genericEvaluate<FEK>(upwind_arg, time);
943 const auto & phi_downwind = functor.template genericEvaluate<FEK>(downwind_arg, time);
950 time_arg = &temp_state;
954 Real max_value(std::numeric_limits<Real>::min()), min_value(std::numeric_limits<Real>::max());
959 const auto & grad_phi_upwind = functor.template genericEvaluate<GFEK>(upwind_arg, *time_arg);
960 const auto & grad_phi_face = functor.template genericEvaluate<GFEK>(face, *time_arg);
1003 mooseAssert(face.
fi,
"this must be non-null");
1011 auto phi_upwind = functor(upwind_arg, time);
1012 auto phi_downwind = functor(downwind_arg, time);
1016 T coeff_upwind, coeff_downwind;
1022 for (
unsigned int i = 0; i < LIBMESH_DIM; ++i)
1024 const auto &component_upwind = phi_upwind(i), component_downwind = phi_downwind(i);
1025 std::tie(coeff_upwind, coeff_downwind) =
interpCoeffs(*limiter,
1030 std::numeric_limits<Real>::max(),
1031 std::numeric_limits<Real>::min(),
1034 ret(i) = coeff_upwind * component_upwind + coeff_downwind * component_downwind;
1044 time_arg = &temp_state;
1048 const auto & grad_phi_upwind = functor.gradient(upwind_arg, *time_arg);
1049 const auto & grad_phi_downwind = functor.gradient(downwind_arg, *time_arg);
1054 for (
unsigned int i = 0; i < LIBMESH_DIM; ++i)
1056 const auto &component_upwind = phi_upwind(i), component_downwind = phi_downwind(i);
1058 grad_face = coeffs.first * grad_phi_upwind.row(i) +
1059 coeffs.second * grad_phi_downwind.row(i);
1062 Real max_value(std::numeric_limits<Real>::min()), min_value(std::numeric_limits<Real>::max());
1103template <
typename T>
1108 typedef typename ContainerGradientType::value_type GradientType;
1109 const GradientType *
const example_gradient =
nullptr;
1111 mooseAssert(face.
fi,
"this must be non-null");
1116 const auto phi_upwind = functor(upwind_arg, time);
1117 const auto phi_downwind = functor(downwind_arg, time);
1121 typename T::value_type coeff_upwind, coeff_downwind;
1126 for (
const auto i : index_range(ret))
1128 const auto &component_upwind = phi_upwind[i], component_downwind = phi_downwind[i];
1129 std::tie(coeff_upwind, coeff_downwind) =
interpCoeffs(*limiter,
1134 std::numeric_limits<Real>::max(),
1135 std::numeric_limits<Real>::min(),
1138 ret[i] = coeff_upwind * component_upwind + coeff_downwind * component_downwind;
1143 const auto grad_phi_upwind = functor.
gradient(upwind_arg, time);
1144 for (
const auto i : index_range(ret))
1146 const auto &component_upwind = phi_upwind[i], component_downwind = phi_downwind[i];
1147 const auto & grad = grad_phi_upwind[i];
1148 std::tie(coeff_upwind, coeff_downwind) =
interpCoeffs(*limiter,
1153 std::numeric_limits<Real>::max(),
1154 std::numeric_limits<Real>::min(),
1157 ret[i] = coeff_upwind * component_upwind + coeff_downwind * component_downwind;
1164template <
typename T>
1173template <
typename T, std::
size_t N>
1185template <
typename SubdomainRestrictable>
DualNumber< Real, DNDerivativeType, true > ADReal
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
A base class interface for both producers and consumers of functor face arguments,...
This data structure is used to store geometric and variable related metadata about each cell face in ...
SubdomainID neighborSubdomainID() const
Point skewnessCorrectionVector() const
Returns the skewness-correction vector (vector between the approximate and real face centroids).
const Point & normal() const
Returns the unit normal vector for the face oriented outward from the face's elem element.
const Elem * neighborPtr() const
SubdomainID elemSubdomainID() const
const Point & neighborCentroid() const
const Point & dCN() const
const Point & elemCentroid() const
Returns the element centroids of the elements on the elem and neighbor sides of the face.
Real gC() const
Return the geometric weighting factor.
const Point & faceCentroid() const
Returns the coordinates of the face centroid.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Every object that can be built by the factory should be derived from this class.
This class provides variable solution values for other classes/objects to bind to when looping over f...
Base class for defining slope limiters for finite volume or potentially reconstructed Discontinuous-G...
static std::unique_ptr< Limiter > build(LimiterType limiter)
virtual bool constant() const =0
Base class template for functor objects.
typename FunctorReturnType< T, FunctorEvaluationKind::Gradient >::type GradientType
This rigmarole makes it so that a user can create functors that return containers (std::vector,...
GradientType gradient(const ElemArg &elem, const StateArg &state) const
Same as their evaluateGradient overloads with the same arguments but allows for caching implementatio...
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
Provides interpolation of face values for non-advection-specific purposes (although it can/will still...
libMesh::CompareTypes< T, T2 >::supertype skewCorrectedLinearInterpolation(const T &value1, const T2 &value2, const T3 &face_gradient, const FaceInfo &fi, const bool one_is_elem)
Linear interpolation with skewness correction using the face gradient.
T containerInterpolate(const FunctorBase< T > &functor, const FaceArg &face, const StateArg &time)
This function interpolates container values at faces in a computational grid using a specified functo...
Scalar rF(const Scalar &phiC, const Scalar &phiD, const Vector &gradC, const RealVectorValue &dCD)
From Moukalled 12.30.
std::pair< Real, Real > computeMinMaxValue(const FunctorBase< T > &functor, const FaceArg &face, const StateArg &time)
This function calculates the minimum and maximum values within a two-cell stencil.
bool setInterpolationMethod(const MooseObject &obj, Moose::FV::InterpMethod &interp_method, const std::string ¶m_name)
Sets one interpolation method.
ADReal gradUDotNormal(const FaceInfo &face_info, const MooseVariableFV< Real > &fv_var, const Moose::StateArg &time, bool correct_skewness=false)
Calculates and returns "grad_u dot normal" on the face to be used for diffusive terms.
@ Venkatakrishnan
Venkatakrishnan limiter (smooth, multidimensional).
libMesh::CompareTypes< T, T2 >::supertype linearInterpolation(const T &value1, const T2 &value2, const FaceInfo &fi, const bool one_is_elem, const InterpMethod interp_method=InterpMethod::Average)
A simple linear interpolation of values between cell centers to a cell face.
T fullLimitedInterpolation(const Limiter< T > &limiter, const T &phi_upwind, const T &phi_downwind, const VectorValue< T > *const grad_phi_upwind, const VectorValue< T > *const grad_phi_face, const Real &max_value, const Real &min_value, const FaceArg &face)
This function performs a full limited interpolation of a variable, taking into account the values and...
InterpMethod
This codifies a set of available ways to interpolate with elem+neighbor solution information to calcu...
@ SkewCorrectedAverage
(gc*elem+(1-gc)*neighbor)+gradient*(rf-rf')
@ HarmonicAverage
1/(gc/elem+(1-gc)/neighbor)
@ Average
gc*elem+(1-gc)*neighbor
libMesh::CompareTypes< T1, T2 >::supertype harmonicInterpolation(const T1 &value1, const T2 &value2, const Real weight1, const Real weight2)
Computes a weighted harmonic mean of Reals, RealVectorValues, and RealTensorValues while accounting f...
std::pair< std::pair< T, T >, std::pair< T, T > > interpCoeffsAndAdvected(const FunctorBase< T > &functor, const FaceArg &face, const StateArg &time)
This function interpolates values using a specified limiter and face argument.
MooseEnum interpolationMethods()
Returns an enum with all the currently supported interpolation methods and the current default for FV...
std::pair< Real, Real > interpCoeffs(const InterpMethod m, const FaceInfo &fi, const bool one_is_elem, const T &face_flux=0.0)
Produce the interpolation coefficients in the equation:
bool onBoundary(const SubdomainRestrictable &obj, const FaceInfo &fi)
Return whether the supplied face is on a boundary of the object's execution.
InputParameters advectedInterpolationParameter()
InterpMethod selectInterpolationMethod(const std::string &interp_method)
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
std::string stringify(const T &t)
conversion to string
FunctorEvaluationKind
An enumeration of possible functor evaluation kinds.
A structure that is used to evaluate Moose functors logically at an element/cell center.
A structure defining a "face" evaluation calling argument for Moose functors.
ElemArg makeNeighbor() const
Make a ElemArg from our data using the face information neighbor.
bool elem_is_upwind
a boolean which states whether the face information element is upwind of the face
ElemArg makeElem() const
Make a ElemArg from our data using the face information element.
bool correct_skewness
Whether to perform skew correction.
Moose::FV::LimiterType limiter_type
a limiter which defines how the functor evaluated on either side of the face should be interpolated t...
const FaceInfo * fi
a face information object which defines our location in space
const Moose::StateArg * state_limiter
A member that can be used to define the instance in which the limiters are executed.
This structure takes an evaluation kind as a template argument and defines a constant expression indi...
State argument for evaluating functors.