FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

faceLimitedGrads.C

Go to the documentation of this file.
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 \*---------------------------------------------------------------------------*/
00025 
00026 #include "faceLimitedGrad.H"
00027 #include <finiteVolume/gaussGrad.H>
00028 #include <finiteVolume/fvMesh.H>
00029 #include <finiteVolume/volMesh.H>
00030 #include <finiteVolume/surfaceMesh.H>
00031 #include <finiteVolume/volFields.H>
00032 #include <finiteVolume/fixedValueFvPatchFields.H>
00033 
00034 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00035 
00036 namespace Foam
00037 {
00038 
00039 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00040 
00041 namespace fv
00042 {
00043 
00044 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00045 
00046 makeFvGradScheme(faceLimitedGrad)
00047 
00048 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00049 
00050 template<class Type>
00051 inline void faceLimitedGrad<Type>::limitFace
00052 (
00053     scalar& limiter,
00054     const scalar maxDelta,
00055     const scalar minDelta,
00056     const scalar extrapolate
00057 ) const
00058 {
00059     if (extrapolate > maxDelta + VSMALL)
00060     {
00061         limiter = min(limiter, maxDelta/extrapolate);
00062     }
00063     else if (extrapolate < minDelta - VSMALL)
00064     {
00065         limiter = min(limiter, minDelta/extrapolate);
00066     }
00067 }
00068 
00069 
00070 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00071 
00072 template<>
00073 tmp<volVectorField> faceLimitedGrad<scalar>::grad
00074 (
00075     const volScalarField& vsf
00076 ) const
00077 {
00078     const fvMesh& mesh = vsf.mesh();
00079 
00080     tmp<volVectorField> tGrad = basicGradScheme_().grad(vsf);
00081 
00082     if (k_ < SMALL)
00083     {
00084         return tGrad;
00085     }
00086 
00087     volVectorField& g = tGrad();
00088 
00089     const unallocLabelList& owner = mesh.owner();
00090     const unallocLabelList& neighbour = mesh.neighbour();
00091 
00092     const volVectorField& C = mesh.C();
00093     const surfaceVectorField& Cf = mesh.Cf();
00094 
00095     // create limiter
00096     scalarField limiter(vsf.internalField().size(), 1.0);
00097 
00098     scalar rk = (1.0/k_ - 1.0);
00099 
00100     forAll(owner, facei)
00101     {
00102         label own = owner[facei];
00103         label nei = neighbour[facei];
00104 
00105         scalar vsfOwn = vsf[own];
00106         scalar vsfNei = vsf[nei];
00107 
00108         scalar maxFace = max(vsfOwn, vsfNei);
00109         scalar minFace = min(vsfOwn, vsfNei);
00110         scalar maxMinFace = rk*(maxFace - minFace);
00111         maxFace += maxMinFace;
00112         minFace -= maxMinFace;
00113 
00114         // owner side
00115         limitFace
00116         (
00117             limiter[own],
00118             maxFace - vsfOwn, minFace - vsfOwn,
00119             (Cf[facei] - C[own]) & g[own]
00120         );
00121 
00122         // neighbour side
00123         limitFace
00124         (
00125             limiter[nei],
00126             maxFace - vsfNei, minFace - vsfNei,
00127             (Cf[facei] - C[nei]) & g[nei]
00128         );
00129     }
00130 
00131     const volScalarField::GeometricBoundaryField& bsf = vsf.boundaryField();
00132 
00133     forAll(bsf, patchi)
00134     {
00135         const fvPatchScalarField& psf = bsf[patchi];
00136 
00137         const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
00138         const vectorField& pCf = Cf.boundaryField()[patchi];
00139 
00140         if (psf.coupled())
00141         {
00142             scalarField psfNei = psf.patchNeighbourField();
00143 
00144             forAll(pOwner, pFacei)
00145             {
00146                 label own = pOwner[pFacei];
00147 
00148                 scalar vsfOwn = vsf[own];
00149                 scalar vsfNei = psfNei[pFacei];
00150 
00151                 scalar maxFace = max(vsfOwn, vsfNei);
00152                 scalar minFace = min(vsfOwn, vsfNei);
00153                 scalar maxMinFace = rk*(maxFace - minFace);
00154                 maxFace += maxMinFace;
00155                 minFace -= maxMinFace;
00156 
00157                 limitFace
00158                 (
00159                     limiter[own],
00160                     maxFace - vsfOwn, minFace - vsfOwn,
00161                     (pCf[pFacei] - C[own]) & g[own]
00162                 );
00163             }
00164         }
00165         else if (psf.fixesValue())
00166         {
00167             forAll(pOwner, pFacei)
00168             {
00169                 label own = pOwner[pFacei];
00170 
00171                 scalar vsfOwn = vsf[own];
00172                 scalar vsfNei = psf[pFacei];
00173 
00174                 scalar maxFace = max(vsfOwn, vsfNei);
00175                 scalar minFace = min(vsfOwn, vsfNei);
00176                 scalar maxMinFace = rk*(maxFace - minFace);
00177                 maxFace += maxMinFace;
00178                 minFace -= maxMinFace;
00179 
00180                 limitFace
00181                 (
00182                     limiter[own],
00183                     maxFace - vsfOwn, minFace - vsfOwn,
00184                     (pCf[pFacei] - C[own]) & g[own]
00185                 );
00186             }
00187         }
00188     }
00189 
00190     if (fv::debug)
00191     {
00192         Info<< "gradient limiter for: " << vsf.name()
00193             << " max = " << gMax(limiter)
00194             << " min = " << gMin(limiter)
00195             << " average: " << gAverage(limiter) << endl;
00196     }
00197 
00198     g.internalField() *= limiter;
00199     g.correctBoundaryConditions();
00200     gaussGrad<scalar>::correctBoundaryConditions(vsf, g);
00201 
00202     return tGrad;
00203 }
00204 
00205 
00206 template<>
00207 tmp<volTensorField> faceLimitedGrad<vector>::grad
00208 (
00209     const volVectorField& vvf
00210 ) const
00211 {
00212     const fvMesh& mesh = vvf.mesh();
00213 
00214     tmp<volTensorField> tGrad = basicGradScheme_().grad(vvf);
00215 
00216     if (k_ < SMALL)
00217     {
00218         return tGrad;
00219     }
00220 
00221     volTensorField& g = tGrad();
00222 
00223     const unallocLabelList& owner = mesh.owner();
00224     const unallocLabelList& neighbour = mesh.neighbour();
00225 
00226     const volVectorField& C = mesh.C();
00227     const surfaceVectorField& Cf = mesh.Cf();
00228 
00229     // create limiter
00230     scalarField limiter(vvf.internalField().size(), 1.0);
00231 
00232     scalar rk = (1.0/k_ - 1.0);
00233 
00234     forAll(owner, facei)
00235     {
00236         label own = owner[facei];
00237         label nei = neighbour[facei];
00238 
00239         vector vvfOwn = vvf[own];
00240         vector vvfNei = vvf[nei];
00241 
00242         // owner side
00243         vector gradf = (Cf[facei] - C[own]) & g[own];
00244 
00245         scalar vsfOwn = gradf & vvfOwn;
00246         scalar vsfNei = gradf & vvfNei;
00247 
00248         scalar maxFace = max(vsfOwn, vsfNei);
00249         scalar minFace = min(vsfOwn, vsfNei);
00250         scalar maxMinFace = rk*(maxFace - minFace);
00251         maxFace += maxMinFace;
00252         minFace -= maxMinFace;
00253 
00254         limitFace
00255         (
00256             limiter[own],
00257             maxFace - vsfOwn, minFace - vsfOwn,
00258             magSqr(gradf)
00259         );
00260 
00261 
00262         // neighbour side
00263         gradf = (Cf[facei] - C[nei]) & g[nei];
00264 
00265         vsfOwn = gradf & vvfOwn;
00266         vsfNei = gradf & vvfNei;
00267 
00268         maxFace = max(vsfOwn, vsfNei);
00269         minFace = min(vsfOwn, vsfNei);
00270 
00271         limitFace
00272         (
00273             limiter[nei],
00274             maxFace - vsfNei, minFace - vsfNei,
00275             magSqr(gradf)
00276         );
00277     }
00278 
00279 
00280     const volVectorField::GeometricBoundaryField& bvf = vvf.boundaryField();
00281 
00282     forAll(bvf, patchi)
00283     {
00284         const fvPatchVectorField& psf = bvf[patchi];
00285 
00286         const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
00287         const vectorField& pCf = Cf.boundaryField()[patchi];
00288 
00289         if (psf.coupled())
00290         {
00291             vectorField psfNei = psf.patchNeighbourField();
00292 
00293             forAll(pOwner, pFacei)
00294             {
00295                 label own = pOwner[pFacei];
00296 
00297                 vector vvfOwn = vvf[own];
00298                 vector vvfNei = psfNei[pFacei];
00299 
00300                 vector gradf = (pCf[pFacei] - C[own]) & g[own];
00301 
00302                 scalar vsfOwn = gradf & vvfOwn;
00303                 scalar vsfNei = gradf & vvfNei;
00304 
00305                 scalar maxFace = max(vsfOwn, vsfNei);
00306                 scalar minFace = min(vsfOwn, vsfNei);
00307                 scalar maxMinFace = rk*(maxFace - minFace);
00308                 maxFace += maxMinFace;
00309                 minFace -= maxMinFace;
00310 
00311                 limitFace
00312                 (
00313                     limiter[own],
00314                     maxFace - vsfOwn, minFace - vsfOwn,
00315                     magSqr(gradf)
00316                 );
00317             }
00318         }
00319         else if (psf.fixesValue())
00320         {
00321             forAll(pOwner, pFacei)
00322             {
00323                 label own = pOwner[pFacei];
00324 
00325                 vector vvfOwn = vvf[own];
00326                 vector vvfNei = psf[pFacei];
00327 
00328                 vector gradf = (pCf[pFacei] - C[own]) & g[own];
00329 
00330                 scalar vsfOwn = gradf & vvfOwn;
00331                 scalar vsfNei = gradf & vvfNei;
00332 
00333                 scalar maxFace = max(vsfOwn, vsfNei);
00334                 scalar minFace = min(vsfOwn, vsfNei);
00335                 scalar maxMinFace = rk*(maxFace - minFace);
00336                 maxFace += maxMinFace;
00337                 minFace -= maxMinFace;
00338 
00339                 limitFace
00340                 (
00341                     limiter[own],
00342                     maxFace - vsfOwn, minFace - vsfOwn,
00343                     magSqr(gradf)
00344                 );
00345             }
00346         }
00347     }
00348 
00349     if (fv::debug)
00350     {
00351         Info<< "gradient limiter for: " << vvf.name()
00352             << " max = " << gMax(limiter)
00353             << " min = " << gMin(limiter)
00354             << " average: " << gAverage(limiter) << endl;
00355     }
00356 
00357     g.internalField() *= limiter;
00358     g.correctBoundaryConditions();
00359     gaussGrad<vector>::correctBoundaryConditions(vvf, g);
00360 
00361     return tGrad;
00362 }
00363 
00364 
00365 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00366 
00367 } // End namespace fv
00368 
00369 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00370 
00371 } // End namespace Foam
00372 
00373 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines