00001 /*---------------------------------------------------------------------------*\ 00002 ========= | 00003 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox 00004 \\ / O peration | 00005 \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. 00006 \\/ M anipulation | 00007 ------------------------------------------------------------------------------- 00008 License 00009 This file is part of OpenFOAM. 00010 00011 OpenFOAM is free software: you can redistribute it and/or modify it 00012 under the terms of the GNU General Public License as published by 00013 the Free Software Foundation, either version 3 of the License, or 00014 (at your option) any later version. 00015 00016 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT 00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00018 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00019 for more details. 00020 00021 You should have received a copy of the GNU General Public License 00022 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. 00023 00024 Class 00025 Foam::filteredLinear2VLimiter 00026 00027 Description 00028 Class to generate weighting factors for the filteredLinear2V 00029 differencing scheme. 00030 00031 The aim is to remove high-frequency modes with "staggering" 00032 characteristics from vector fields by comparing the face gradient in 00033 the direction of maximum gradient with both neighbouring cell gradients 00034 and introduce small amounts of upwind in order to damp these modes. 00035 00036 Used in conjunction with the template class LimitedScheme. 00037 00038 SourceFiles 00039 filteredLinear2V.C 00040 00041 \*---------------------------------------------------------------------------*/ 00042 00043 #ifndef filteredLinear2V_H 00044 #define filteredLinear2V_H 00045 00046 #include <OpenFOAM/vector.H> 00047 00048 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 00049 00050 namespace Foam 00051 { 00052 00053 /*---------------------------------------------------------------------------*\ 00054 Class filteredLinear2VLimiter Declaration 00055 \*---------------------------------------------------------------------------*/ 00056 00057 template<class LimiterFunc> 00058 class filteredLinear2VLimiter 00059 : 00060 public LimiterFunc 00061 { 00062 // Private data 00063 00064 // Scaling corefficient for the gradient ratio, 00065 // 0 = linear 00066 // 1 = fully limited 00067 scalar k_; 00068 00069 // Maximum allowed overshoot/undershoot relative to the difference 00070 // across the face. 00071 // On input: 00072 // 0 = no overshoot/undershoot 00073 // 1 = overshoot/undershoot equal to the difference across the face 00074 // Note: After input 1 is added to l_ 00075 scalar l_; 00076 00077 00078 public: 00079 00080 filteredLinear2VLimiter(Istream& is) 00081 : 00082 k_(readScalar(is)), 00083 l_(readScalar(is)) 00084 { 00085 if (k_ < 0 || k_ > 1) 00086 { 00087 FatalIOErrorIn("filteredLinear2VLimiter(Istream& is)", is) 00088 << "coefficient = " << k_ 00089 << " should be >= 0 and <= 1" 00090 << exit(FatalIOError); 00091 } 00092 00093 if (l_ < 0 || l_ > 1) 00094 { 00095 FatalIOErrorIn("filteredLinear2VLimiter(Istream& is)", is) 00096 << "coefficient = " << l_ 00097 << " should be >= 0 and <= 1" 00098 << exit(FatalIOError); 00099 } 00100 00101 l_ += 1.0; 00102 } 00103 00104 scalar limiter 00105 ( 00106 const scalar cdWeight, 00107 const scalar faceFlux, 00108 const typename LimiterFunc::phiType& phiP, 00109 const typename LimiterFunc::phiType& phiN, 00110 const typename LimiterFunc::gradPhiType& gradcP, 00111 const typename LimiterFunc::gradPhiType& gradcN, 00112 const vector& d 00113 ) const 00114 { 00115 // Difference across face 00116 vector dfV = phiN - phiP; 00117 00118 // Scalar difference across the face 00119 // in the direction in which the difference is largest 00120 scalar df = dfV & dfV; 00121 00122 // Twice differences across face-neighbour cells 00123 // in the direction in which the face-difference is largest 00124 scalar tdcP = 2*(dfV & (d & gradcP)); 00125 scalar tdcN = 2*(dfV & (d & gradcN)); 00126 00127 // Calculate the limiter according to the sign of the face difference 00128 scalar limiter; 00129 00130 if (df > 0) 00131 { 00132 limiter = l_ 00133 - k_*min(max(df - tdcP, 0), max(df - tdcN, 0)) 00134 /(max(mag(df), max(mag(tdcP), mag(tdcN))) + VSMALL); 00135 } 00136 else 00137 { 00138 limiter = l_ 00139 - k_*min(max(tdcP - df, 0), max(tdcN - df, 0)) 00140 /(max(mag(df), max(mag(tdcP), mag(tdcN))) + VSMALL); 00141 } 00142 00143 // Limit the limiter between linear and upwind 00144 return max(min(limiter, 1), 0); 00145 } 00146 }; 00147 00148 00149 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 00150 00151 } // End namespace Foam 00152 00153 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 00154 00155 #endif 00156 00157 // ************************ vim: set sw=4 sts=4 et: ************************ //