initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / finiteVolume / finiteVolume / gradSchemes / limitedGradSchemes / faceLimitedGrad / faceLimitedGrads.C
blobafaf398fbc3b82c24852480ee6650e136200ef06
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software; you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24     
25 \*---------------------------------------------------------------------------*/
27 #include "faceLimitedGrad.H"
28 #include "gaussGrad.H"
29 #include "fvMesh.H"
30 #include "volMesh.H"
31 #include "surfaceMesh.H"
32 #include "volFields.H"
33 #include "fixedValueFvPatchFields.H"
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 namespace Foam
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 namespace fv
45 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
47 makeFvGradScheme(faceLimitedGrad)
49 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
51 template<class Type>
52 inline void faceLimitedGrad<Type>::limitFace
54     scalar& limiter,
55     const scalar maxDelta,
56     const scalar minDelta,
57     const scalar extrapolate
58 ) const
60     if (extrapolate > maxDelta + VSMALL)
61     {
62         limiter = min(limiter, maxDelta/extrapolate);
63     }
64     else if (extrapolate < minDelta - VSMALL)
65     {
66         limiter = min(limiter, minDelta/extrapolate);
67     }
71 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
73 template<>
74 tmp<volVectorField> faceLimitedGrad<scalar>::grad
76     const volScalarField& vsf
77 ) const
79     const fvMesh& mesh = vsf.mesh();
81     tmp<volVectorField> tGrad = basicGradScheme_().grad(vsf);
83     if (k_ < SMALL)
84     {
85         return tGrad;
86     }
88     volVectorField& g = tGrad();
90     const unallocLabelList& owner = mesh.owner();
91     const unallocLabelList& neighbour = mesh.neighbour();
93     const volVectorField& C = mesh.C();
94     const surfaceVectorField& Cf = mesh.Cf();
96     // create limiter
97     scalarField limiter(vsf.internalField().size(), 1.0);
99     scalar rk = (1.0/k_ - 1.0);
101     forAll(owner, facei)
102     {
103         label own = owner[facei];
104         label nei = neighbour[facei];
106         scalar vsfOwn = vsf[own];
107         scalar vsfNei = vsf[nei];
109         scalar maxFace = max(vsfOwn, vsfNei);
110         scalar minFace = min(vsfOwn, vsfNei);
111         scalar maxMinFace = rk*(maxFace - minFace);
112         maxFace += maxMinFace;
113         minFace -= maxMinFace;
115         // owner side
116         limitFace
117         (
118             limiter[own],
119             maxFace - vsfOwn, minFace - vsfOwn,
120             (Cf[facei] - C[own]) & g[own]
121         );
123         // neighbour side
124         limitFace
125         (
126             limiter[nei],
127             maxFace - vsfNei, minFace - vsfNei,
128             (Cf[facei] - C[nei]) & g[nei]
129         );
130     }
132     const volScalarField::GeometricBoundaryField& bsf = vsf.boundaryField();
134     forAll(bsf, patchi)
135     {
136         const fvPatchScalarField& psf = bsf[patchi];
138         const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
139         const vectorField& pCf = Cf.boundaryField()[patchi];
141         if (psf.coupled())
142         {
143             scalarField psfNei = psf.patchNeighbourField();
145             forAll(pOwner, pFacei)
146             {
147                 label own = pOwner[pFacei];
149                 scalar vsfOwn = vsf[own];
150                 scalar vsfNei = psfNei[pFacei];
152                 scalar maxFace = max(vsfOwn, vsfNei);
153                 scalar minFace = min(vsfOwn, vsfNei);
154                 scalar maxMinFace = rk*(maxFace - minFace);
155                 maxFace += maxMinFace;
156                 minFace -= maxMinFace;
158                 limitFace
159                 (
160                     limiter[own],
161                     maxFace - vsfOwn, minFace - vsfOwn,
162                     (pCf[pFacei] - C[own]) & g[own]
163                 );
164             }
165         }
166         else if (psf.fixesValue())
167         {
168             forAll(pOwner, pFacei)
169             {
170                 label own = pOwner[pFacei];
172                 scalar vsfOwn = vsf[own];
173                 scalar vsfNei = psf[pFacei];
175                 scalar maxFace = max(vsfOwn, vsfNei);
176                 scalar minFace = min(vsfOwn, vsfNei);
177                 scalar maxMinFace = rk*(maxFace - minFace);
178                 maxFace += maxMinFace;
179                 minFace -= maxMinFace;
181                 limitFace
182                 (
183                     limiter[own],
184                     maxFace - vsfOwn, minFace - vsfOwn,
185                     (pCf[pFacei] - C[own]) & g[own]
186                 );
187             }
188         }
189     }
191     if (fv::debug)
192     {
193         Info<< "gradient limiter for: " << vsf.name()
194             << " max = " << gMax(limiter)
195             << " min = " << gMin(limiter)
196             << " average: " << gAverage(limiter) << endl;
197     }
199     g.internalField() *= limiter;
200     g.correctBoundaryConditions();
201     gaussGrad<scalar>::correctBoundaryConditions(vsf, g);
203     return tGrad;
207 template<>
208 tmp<volTensorField> faceLimitedGrad<vector>::grad
210     const volVectorField& vvf
211 ) const
213     const fvMesh& mesh = vvf.mesh();
215     tmp<volTensorField> tGrad = basicGradScheme_().grad(vvf);
217     if (k_ < SMALL)
218     {
219         return tGrad;
220     }
222     volTensorField& g = tGrad();
224     const unallocLabelList& owner = mesh.owner();
225     const unallocLabelList& neighbour = mesh.neighbour();
227     const volVectorField& C = mesh.C();
228     const surfaceVectorField& Cf = mesh.Cf();
230     // create limiter
231     scalarField limiter(vvf.internalField().size(), 1.0);
233     scalar rk = (1.0/k_ - 1.0);
235     forAll(owner, facei)
236     {
237         label own = owner[facei];
238         label nei = neighbour[facei];
240         vector vvfOwn = vvf[own];
241         vector vvfNei = vvf[nei];
243         // owner side
244         vector gradf = (Cf[facei] - C[own]) & g[own];
246         scalar vsfOwn = gradf & vvfOwn;
247         scalar vsfNei = gradf & vvfNei;
249         scalar maxFace = max(vsfOwn, vsfNei);
250         scalar minFace = min(vsfOwn, vsfNei);
251         scalar maxMinFace = rk*(maxFace - minFace);
252         maxFace += maxMinFace;
253         minFace -= maxMinFace;
255         limitFace
256         (
257             limiter[own],
258             maxFace - vsfOwn, minFace - vsfOwn,
259             magSqr(gradf)
260         );
263         // neighbour side
264         gradf = (Cf[facei] - C[nei]) & g[nei];
266         vsfOwn = gradf & vvfOwn;
267         vsfNei = gradf & vvfNei;
269         maxFace = max(vsfOwn, vsfNei);
270         minFace = min(vsfOwn, vsfNei);
272         limitFace
273         (
274             limiter[nei],
275             maxFace - vsfNei, minFace - vsfNei,
276             magSqr(gradf)
277         );
278     }
281     const volVectorField::GeometricBoundaryField& bvf = vvf.boundaryField();
283     forAll(bvf, patchi)
284     {
285         const fvPatchVectorField& psf = bvf[patchi];
287         const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
288         const vectorField& pCf = Cf.boundaryField()[patchi];
290         if (psf.coupled())
291         {
292             vectorField psfNei = psf.patchNeighbourField();
294             forAll(pOwner, pFacei)
295             {
296                 label own = pOwner[pFacei];
298                 vector vvfOwn = vvf[own];
299                 vector vvfNei = psfNei[pFacei];
301                 vector gradf = (pCf[pFacei] - C[own]) & g[own];
303                 scalar vsfOwn = gradf & vvfOwn;
304                 scalar vsfNei = gradf & vvfNei;
306                 scalar maxFace = max(vsfOwn, vsfNei);
307                 scalar minFace = min(vsfOwn, vsfNei);
308                 scalar maxMinFace = rk*(maxFace - minFace);
309                 maxFace += maxMinFace;
310                 minFace -= maxMinFace;
312                 limitFace
313                 (
314                     limiter[own],
315                     maxFace - vsfOwn, minFace - vsfOwn,
316                     magSqr(gradf)
317                 );
318             }
319         }
320         else if (psf.fixesValue())
321         {
322             forAll(pOwner, pFacei)
323             {
324                 label own = pOwner[pFacei];
326                 vector vvfOwn = vvf[own];
327                 vector vvfNei = psf[pFacei];
329                 vector gradf = (pCf[pFacei] - C[own]) & g[own];
331                 scalar vsfOwn = gradf & vvfOwn;
332                 scalar vsfNei = gradf & vvfNei;
334                 scalar maxFace = max(vsfOwn, vsfNei);
335                 scalar minFace = min(vsfOwn, vsfNei);
336                 scalar maxMinFace = rk*(maxFace - minFace);
337                 maxFace += maxMinFace;
338                 minFace -= maxMinFace;
340                 limitFace
341                 (
342                     limiter[own],
343                     maxFace - vsfOwn, minFace - vsfOwn,
344                     magSqr(gradf)
345                 );
346             }
347         }
348     }
350     if (fv::debug)
351     {
352         Info<< "gradient limiter for: " << vvf.name()
353             << " max = " << gMax(limiter)
354             << " min = " << gMin(limiter)
355             << " average: " << gAverage(limiter) << endl;
356     }
358     g.internalField() *= limiter;
359     g.correctBoundaryConditions();
360     gaussGrad<vector>::correctBoundaryConditions(vvf, g);
362     return tGrad;
366 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
368 } // End namespace fv
370 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
372 } // End namespace Foam
374 // ************************************************************************* //