Line data Source code
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 : 10 : #pragma once 11 : 12 : #include "Limiter.h" 13 : #include "MathFVUtils.h" 14 : 15 : namespace Moose 16 : { 17 : namespace FV 18 : { 19 : /** 20 : * The Venkatakrishnan limiter is derived from the following equations: 21 : * 22 : * 1. Calculation of the face delta: 23 : * \f[ 24 : * \Delta_{\text{face}} = \nabla \phi_{\text{upwind}} \cdot (\mathbf{x}_{\text{face}} - 25 : * \mathbf{x}_{\text{cell}}) \f] 26 : * 27 : * 2. Calculation of the deltas for maximum and minimum values relative to the upwind value with a 28 : * small perturbation to avoid division by zero: \f[ \Delta_{\text{max}} = \phi_{\text{max}} - 29 : * \phi_{\text{upwind}} + 1e-10 \f] \f[ \Delta_{\text{min}} = \phi_{\text{min}} - 30 : * \phi_{\text{upwind}} + 1e-10 \f] 31 : * 32 : * 3. Calculation of the gradient ratio coefficient \( r_f \): 33 : * \f[ 34 : * r_f = \begin{cases} 35 : * \frac{\Delta_{\text{face}}}{\Delta_{\text{max}}} & \text{if } \Delta_{\text{face}} \geq 0 \\ 36 : * \frac{\Delta_{\text{face}}}{\Delta_{\text{min}}} & \text{otherwise} 37 : * \end{cases} 38 : * \f] 39 : * 40 : * 4. Venkatakrishnan limiter formula (Venkatakrishnan, 1993): 41 : * \f[ 42 : * \beta(r_f) = \frac{2 r_f + 1.0}{r_f (2 r_f + 1.0) + 1.0} 43 : * \f] 44 : * 45 : * @tparam T The data type of the scalar values and the return type. 46 : */ 47 : template <typename T> 48 : class VenkatakrishnanLimiter : public Limiter<T> 49 : { 50 : public: 51 : /** 52 : * This method overrides the pure virtual `limit` method in the base `Limiter` class. 53 : * It calculates the flux limiting ratio based on the Venkatakrishnan limiter formula. 54 : * 55 : * @param phi_upwind Scalar value at the upwind location. 56 : * @param grad_phi_upwind Pointer to the gradient vector at the upwind location. 57 : * @param max_value The maximum value in the current element. 58 : * @param min_value The minimum value in the current element. 59 : * @param fi Pointer to the face information structure. 60 : * @param fi_elem_is_upwind Boolean flag indicating if the current element is upwind. 61 : * @return The computed flux limiting ratio. 62 : */ 63 2119040 : T limit(const T & phi_upwind, 64 : const T & /* phi_downwind */, 65 : const VectorValue<T> * grad_phi_upwind, 66 : const VectorValue<T> * /* grad_phi_downwind */, 67 : const RealVectorValue & /* dCD */, 68 : const Real & max_value, 69 : const Real & min_value, 70 : const FaceInfo * fi, 71 : const bool & fi_elem_is_upwind) const override final 72 : { 73 2119040 : const auto face_centroid = fi->faceCentroid(); 74 2119040 : const auto cell_centroid = fi_elem_is_upwind ? fi->elemCentroid() : fi->neighborCentroid(); 75 : 76 2119040 : const auto delta_face = (*grad_phi_upwind) * (face_centroid - cell_centroid); 77 2119040 : const auto delta_max = std::abs(max_value - phi_upwind) + 1e-10; 78 2119040 : const auto delta_min = std::abs(min_value - phi_upwind) + 1e-10; 79 : 80 2119040 : const auto rf = 81 2119040 : delta_face >= 0 ? std::abs(delta_face) / delta_max : std::abs(delta_face) / delta_min; 82 : 83 4238080 : return (2 * rf + 1.0) / (rf * (2 * rf + 1.0) + 1.0); 84 2119040 : } 85 : 86 0 : bool constant() const override final { return false; } 87 : 88 0 : InterpMethod interpMethod() const override final { return InterpMethod::Venkatakrishnan; } 89 : 90 2119040 : VenkatakrishnanLimiter() = default; 91 : }; 92 : } 93 : }