17 #include "metaphysicl/raw_type.h" 18 #include "libmesh/compare_types.h" 19 #include "libmesh/elem.h" 95 const std::string & param_name);
115 template <
typename T = Real>
116 std::pair<Real, 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");
151 template <
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;
178 template <
typename T1,
typename T2>
183 const bool one_is_elem)
187 static_assert(std::is_same<
typename MetaPhysicL::RawType<T1>::value_type,
188 typename MetaPhysicL::RawType<T2>::value_type>::
value,
189 "The input values for harmonic interpolation need to have the same raw-value!");
203 if (value1 * value2 <= 0)
206 ") must be of the same sign for harmonic interpolation");
208 return 1.0 / (coeffs.first / value1 + coeffs.second / value2);
217 if (value1(i) * value2(i) <= 0)
218 mooseWarning(
"Component " + std::to_string(i) +
" of input values (" +
221 ") must be of the same sign for harmonic interpolation");
223 result(i) = 1.0 / (coeffs.first / value1(i) + coeffs.second / value2(i));
236 if (value1(i, j) * value2(i, j) <= 0)
237 mooseWarning(
"Component (" + std::to_string(i) +
"," + std::to_string(j) +
238 ") of input values (" +
241 ") must be of the same sign for harmonic interpolation");
243 result(i, j) = 1.0 / (coeffs.first / value1(i, j) + coeffs.second / value2(i, j));
252 static_assert(Moose::always_false<T1>,
253 "Harmonic interpolation is not implemented for the used type!");
262 template <
typename T,
typename T2,
typename T3>
266 const T3 & face_gradient,
268 const bool one_is_elem)
272 auto value = (coeffs.first * value1 + coeffs.second * value2) +
283 template <
typename T,
typename T2,
typename T3>
290 const bool one_is_elem)
302 mooseError(
"unsupported interpolation method for interpolate() function");
310 template <
typename T, FunctorEvaluationKind FEK = FunctorEvaluationKind::Value>
315 "Only Value and Dot evaluations currently supported");
317 "this interpolation method is meant for linear interpolations");
320 "We must have a non-null face_info in order to prepare our ElemFromFace tuples");
324 const auto elem_arg = face.
makeElem();
327 const auto elem_eval = functor.template genericEvaluate<FEK>(elem_arg, time);
328 const auto neighbor_eval = functor.template genericEvaluate<FEK>(neighbor_arg, time);
338 const auto surface_gradient = functor.template genericEvaluate<GFEK>(new_face, time);
341 elem_eval, neighbor_eval, surface_gradient, *face.
fi,
true);
350 template <
typename T1,
353 template <
typename>
class Vector1,
354 template <
typename>
class Vector2>
357 Vector1<T1> & result,
358 const T2 & fi_elem_advected,
359 const T2 & fi_neighbor_advected,
360 const Vector2<T3> & fi_elem_advector,
361 const Vector2<T3> & fi_neighbor_advector,
368 fi_neighbor_advected * fi_neighbor_advector,
378 Real elem_coeff, neighbor_coeff;
379 if (face_advector * fi.
normal() > 0)
380 elem_coeff = 1, neighbor_coeff = 0;
382 elem_coeff = 0, neighbor_coeff = 1;
384 result = elem_coeff * fi_elem_advected * fi_elem_advector +
385 neighbor_coeff * fi_neighbor_advected * fi_neighbor_advector;
389 mooseError(
"unsupported interpolation method for FVFaceInterface::interpolate");
401 template <
typename T,
typename T2,
typename T3,
typename Vector>
407 const Vector & advector,
409 const bool one_is_elem)
412 result = coeffs.first * value1 + coeffs.second * value2;
421 bool correct_skewness =
false);
446 template <
typename Scalar,
typename Vector>
450 const Scalar denom = phiD - phiC;
451 const Scalar grad_dot = gradC * dCD;
456 const Real denom_sign =
460 const Scalar safe = denom + denom_sign *
eps;
461 return 2.0 * grad_dot / safe - 1.0;
475 template <
typename T>
478 const T & phi_upwind,
479 const T & phi_downwind,
482 const Real & max_value,
483 const Real & min_value,
485 const bool fi_elem_is_upwind)
488 const auto beta = limiter(phi_upwind,
492 fi_elem_is_upwind ? fi.
dCN() : Point(-fi.
dCN()),
498 const auto w_f = fi_elem_is_upwind ? fi.
gC() : (1. - fi.
gC());
500 const auto g = beta * (1. - w_f);
502 return std::make_pair(1. - g, g);
508 template <
typename Scalar,
510 typename Enable =
typename std::enable_if<libMesh::ScalarTraits<Scalar>::value>::type>
513 const Scalar & phi_upwind,
514 const Scalar & phi_downwind,
515 const Vector *
const grad_phi_upwind,
517 const bool fi_elem_is_upwind)
529 return pr.first * phi_upwind + pr.second * phi_downwind;
535 template <
typename Limiter,
typename T,
typename Tensor>
538 const TypeVector<T> & phi_upwind,
539 const TypeVector<T> & phi_downwind,
540 const Tensor *
const grad_phi_upwind,
542 const bool fi_elem_is_upwind)
544 mooseAssert(limiter.
constant() || grad_phi_upwind,
545 "Non-null gradient only supported for constant limiters.");
549 for (
const auto i :
make_range(
unsigned(LIBMESH_DIM)))
555 interpolate(limiter, phi_upwind(i), phi_downwind(i), &gradient, fi, fi_elem_is_upwind);
559 limiter, phi_upwind(i), phi_downwind(i), gradient_example, fi, fi_elem_is_upwind);
583 template <
typename T>
586 const T & phi_upwind,
587 const T & phi_downwind,
588 const VectorValue<T> *
const grad_phi_upwind,
589 const VectorValue<T> *
const grad_phi_face,
590 const Real & max_value,
591 const Real & min_value,
598 const auto beta = limiter(phi_upwind,
610 const auto & cell_centroid =
616 delta_face = (*grad_phi_upwind) * (face_centroid - cell_centroid);
618 delta_face = (*grad_phi_face) * (face_centroid - cell_centroid);
621 return phi_upwind + beta * delta_face;
646 template <
typename T,
648 typename Enable =
typename std::enable_if<ScalarTraits<T>::value>::type>
649 std::pair<Real, Real>
656 for (
const auto neighbor : (*face.
fi).elem().neighbor_ptr_range())
659 if (neighbor ==
nullptr)
663 const ElemArg local_cell_arg = {neighbor,
false};
671 for (
const auto neighbor : (*face.
fi).neighbor().neighbor_ptr_range())
674 if (neighbor ==
nullptr)
678 const ElemArg local_cell_arg = {neighbor,
false};
686 return std::make_pair(max_value, min_value);
714 template <
typename T>
715 std::pair<Real, Real>
719 const unsigned int & component)
725 for (
const auto neighbor : (*face.
fi).elem().neighbor_ptr_range())
728 if (neighbor ==
nullptr)
733 const ElemArg local_cell_arg = {neighbor,
false};
740 for (
const auto neighbor : (*face.
fi).neighbor().neighbor_ptr_range())
743 if (neighbor ==
nullptr)
748 const ElemArg local_cell_arg = {neighbor,
false};
755 return std::make_pair(max_value, min_value);
786 template <
typename T,
788 typename Enable =
typename std::enable_if<libMesh::ScalarTraits<T>::value>::type>
789 std::pair<std::pair<T, T>, std::pair<T, T>>
794 "Only Value and Dot evaluations currently supported");
799 static const GradientType
zero(0);
801 mooseAssert(face.
fi,
"this must be non-null");
811 auto phi_upwind = functor.template genericEvaluate<FEK>(upwind_arg, time);
812 auto phi_downwind = functor.template genericEvaluate<FEK>(downwind_arg, time);
815 std::pair<T, T> interp_coeffs;
836 time_arg = &temp_state;
846 const auto grad_phi_upwind = functor.template genericEvaluate<GFEK>(upwind_arg, *time_arg);
847 const auto grad_phi_face = functor.template genericEvaluate<GFEK>(face, *time_arg);
858 face.elem_is_upwind);
863 return std::make_pair(std::move(interp_coeffs),
864 std::make_pair(std::move(phi_upwind), std::move(phi_downwind)));
866 return std::make_pair(
867 std::make_pair(std::move(interp_coeffs.second), std::move(interp_coeffs.first)),
868 std::make_pair(std::move(phi_downwind), std::move(phi_upwind)));
894 template <
typename T,
896 typename Enable =
typename std::enable_if<libMesh::ScalarTraits<T>::value>::type>
902 "Only Value and Dot evaluations currently supported");
907 return linearInterpolation<T, FEK>(functor, face, time);
913 const auto [interp_coeffs, advected] = interpCoeffsAndAdvected<T, FEK>(functor, face, time);
915 return interp_coeffs.first * advected.first + interp_coeffs.second * advected.second;
922 static const GradientType
zero(0);
923 const auto & limiter =
927 const auto & upwind_arg = face.elem_is_upwind ? face.makeElem() : face.makeNeighbor();
928 const auto & downwind_arg = face.elem_is_upwind ? face.makeNeighbor() : face.makeElem();
929 const auto & phi_upwind = functor.template genericEvaluate<FEK>(upwind_arg, time);
930 const auto & phi_downwind = functor.template genericEvaluate<FEK>(downwind_arg, time);
933 auto * time_arg = face.state_limiter;
937 time_arg = &temp_state;
946 const auto & grad_phi_upwind = functor.template genericEvaluate<GFEK>(upwind_arg, *time_arg);
947 const auto & grad_phi_face = functor.template genericEvaluate<GFEK>(face, *time_arg);
981 template <
typename T>
990 mooseAssert(face.
fi,
"this must be non-null");
998 auto phi_upwind = functor(upwind_arg, time);
999 auto phi_downwind = functor(downwind_arg, time);
1003 T coeff_upwind, coeff_downwind;
1009 for (
unsigned int i = 0; i < LIBMESH_DIM; ++i)
1011 const auto &component_upwind = phi_upwind(i), component_downwind = phi_downwind(i);
1012 std::tie(coeff_upwind, coeff_downwind) =
interpCoeffs(*limiter,
1021 ret(i) = coeff_upwind * component_upwind + coeff_downwind * component_downwind;
1031 time_arg = &temp_state;
1035 const auto & grad_phi_upwind = functor.gradient(upwind_arg, *time_arg);
1036 const auto & grad_phi_downwind = functor.gradient(downwind_arg, *time_arg);
1041 for (
unsigned int i = 0; i < LIBMESH_DIM; ++i)
1043 const auto &component_upwind = phi_upwind(i), component_downwind = phi_downwind(i);
1045 grad_face = coeffs.first * grad_phi_upwind.row(i) +
1046 coeffs.second * grad_phi_downwind.row(i);
1090 template <
typename T>
1095 typedef typename ContainerGradientType::value_type GradientType;
1096 const GradientType *
const example_gradient =
nullptr;
1098 mooseAssert(face.
fi,
"this must be non-null");
1103 const auto phi_upwind = functor(upwind_arg, time);
1104 const auto phi_downwind = functor(downwind_arg, time);
1108 typename T::value_type coeff_upwind, coeff_downwind;
1115 const auto &component_upwind = phi_upwind[i], component_downwind = phi_downwind[i];
1116 std::tie(coeff_upwind, coeff_downwind) =
interpCoeffs(*limiter,
1125 ret[i] = coeff_upwind * component_upwind + coeff_downwind * component_downwind;
1130 const auto grad_phi_upwind = functor.
gradient(upwind_arg, time);
1133 const auto &component_upwind = phi_upwind[i], component_downwind = phi_downwind[i];
1134 const auto & grad = grad_phi_upwind[i];
1135 std::tie(coeff_upwind, coeff_downwind) =
interpCoeffs(*limiter,
1144 ret[i] = coeff_upwind * component_upwind + coeff_downwind * component_downwind;
1151 template <
typename T>
1160 template <
typename T, std::
size_t N>
1172 template <
typename SubdomainRestrictable>
int eps(unsigned int i, unsigned int j)
2D version
Base class template for functor objects.
libMesh::CompareTypes< T1, T2 >::supertype harmonicInterpolation(const T1 &value1, const T2 &value2, const FaceInfo &fi, const bool one_is_elem)
Computes the harmonic mean (1/(gc/value1+(1-gc)/value2)) of Reals, RealVectorValues and RealTensorVal...
Point skewnessCorrectionVector() const
Returns the skewness-correction vector (vector between the approximate and real face centroids)...
Base class for defining slope limiters for finite volume or potentially reconstructed Discontinuous-G...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
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:
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
1/(gc/elem+(1-gc)/neighbor)
const Point & faceCentroid() const
Returns the coordinates of the face centroid.
bool correct_skewness
Whether to perform skew correction.
Scalar rF(const Scalar &phiC, const Scalar &phiD, const Vector &gradC, const RealVectorValue &dCD)
From Moukalled 12.30.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
const Point & neighborCentroid() const
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.
DualNumber< Real, DNDerivativeType, true > ADReal
MooseEnum interpolationMethods()
Returns an enum with all the currently supported interpolation methods and the current default for FV...
const Moose::StateArg * state_limiter
A member that can be used to define the instance in which the limiters are executed.
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...
typename FunctorReturnType< T, FunctorEvaluationKind::Gradient >::type GradientType
This rigmarole makes it so that a user can create functors that return containers (std::vector...
auto max(const L &left, const R &right)
SubdomainID elemSubdomainID() const
FunctorEvaluationKind
An enumeration of possible functor evaluation kinds.
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.
This data structure is used to store geometric and variable related metadata about each cell face in ...
virtual bool constant() const =0
const Elem * neighborPtr() const
const Point & elemCentroid() const
Returns the element centroids of the elements on the elem and neighbor sides of the face...
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
InputParameters advectedInterpolationParameter()
A structure defining a "face" evaluation calling argument for Moose functors.
Every object that can be built by the factory should be derived from this class.
const FaceInfo * fi
a face information object which defines our location in space
Real gC() const
Return the geometric weighting factor.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Moose::FV::LimiterType limiter_type
a limiter which defines how the functor evaluated on either side of the face should be interpolated t...
A structure that is used to evaluate Moose functors logically at an element/cell center.
ElemArg makeNeighbor() const
Make a ElemArg from our data using the face information neighbor.
const Point & normal() const
Returns the unit normal vector for the face oriented outward from the face's elem element...
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.
std::string stringify(const T &t)
conversion to string
This structure takes an evaluation kind as a template argument and defines a constant expression indi...
bool onBoundary(const SubdomainRestrictable &obj, const FaceInfo &fi)
Return whether the supplied face is on a boundary of the object's execution.
(gc*elem+(1-gc)*neighbor)+gradient*(rf-rf')
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...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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.
GradientType gradient(const ElemArg &elem, const StateArg &state) const
Same as their evaluateGradient overloads with the same arguments but allows for caching implementatio...
IntRange< T > make_range(T beg, T end)
SubdomainID neighborSubdomainID() const
State argument for evaluating functors.
InterpMethod selectInterpolationMethod(const std::string &interp_method)
Venkatakrishnan limiter (smooth, multidimensional).
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
bool elem_is_upwind
a boolean which states whether the face information element is upwind of the face ...
This class provides variable solution values for other classes/objects to bind to when looping over 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.
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...
InterpMethod
This codifies a set of available ways to interpolate with elem+neighbor solution information to calcu...
auto min(const L &left, const R &right)
A base class interface for both producers and consumers of functor face arguments, e.g.
ElemArg makeElem() const
Make a ElemArg from our data using the face information element.
static std::unique_ptr< Limiter > build(LimiterType limiter)
auto index_range(const T &sizable)
bool setInterpolationMethod(const MooseObject &obj, Moose::FV::InterpMethod &interp_method, const std::string ¶m_name)
Sets one interpolation method.
const Point & dCN() const