1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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
25 \*---------------------------------------------------------------------------*/
27 #include "faceLimitedGrad.H"
28 #include "gaussGrad.H"
31 #include "surfaceMesh.H"
32 #include "volFields.H"
33 #include "fixedValueFvPatchFields.H"
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
47 makeFvGradScheme(faceLimitedGrad)
49 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
52 inline void faceLimitedGrad<Type>::limitFace
55 const scalar maxDelta,
56 const scalar minDelta,
57 const scalar extrapolate
60 if (extrapolate > maxDelta + VSMALL)
62 limiter = min(limiter, maxDelta/extrapolate);
64 else if (extrapolate < minDelta - VSMALL)
66 limiter = min(limiter, minDelta/extrapolate);
71 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
74 tmp<volVectorField> faceLimitedGrad<scalar>::grad
76 const volScalarField& vsf
79 const fvMesh& mesh = vsf.mesh();
81 tmp<volVectorField> tGrad = basicGradScheme_().grad(vsf);
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();
97 scalarField limiter(vsf.internalField().size(), 1.0);
99 scalar rk = (1.0/k_ - 1.0);
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;
119 maxFace - vsfOwn, minFace - vsfOwn,
120 (Cf[facei] - C[own]) & g[own]
127 maxFace - vsfNei, minFace - vsfNei,
128 (Cf[facei] - C[nei]) & g[nei]
132 const volScalarField::GeometricBoundaryField& bsf = vsf.boundaryField();
136 const fvPatchScalarField& psf = bsf[patchi];
138 const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
139 const vectorField& pCf = Cf.boundaryField()[patchi];
143 scalarField psfNei = psf.patchNeighbourField();
145 forAll(pOwner, pFacei)
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;
161 maxFace - vsfOwn, minFace - vsfOwn,
162 (pCf[pFacei] - C[own]) & g[own]
166 else if (psf.fixesValue())
168 forAll(pOwner, pFacei)
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;
184 maxFace - vsfOwn, minFace - vsfOwn,
185 (pCf[pFacei] - C[own]) & g[own]
193 Info<< "gradient limiter for: " << vsf.name()
194 << " max = " << gMax(limiter)
195 << " min = " << gMin(limiter)
196 << " average: " << gAverage(limiter) << endl;
199 g.internalField() *= limiter;
200 g.correctBoundaryConditions();
201 gaussGrad<scalar>::correctBoundaryConditions(vsf, g);
208 tmp<volTensorField> faceLimitedGrad<vector>::grad
210 const volVectorField& vvf
213 const fvMesh& mesh = vvf.mesh();
215 tmp<volTensorField> tGrad = basicGradScheme_().grad(vvf);
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();
231 scalarField limiter(vvf.internalField().size(), 1.0);
233 scalar rk = (1.0/k_ - 1.0);
237 label own = owner[facei];
238 label nei = neighbour[facei];
240 vector vvfOwn = vvf[own];
241 vector vvfNei = vvf[nei];
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;
258 maxFace - vsfOwn, minFace - vsfOwn,
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);
275 maxFace - vsfNei, minFace - vsfNei,
281 const volVectorField::GeometricBoundaryField& bvf = vvf.boundaryField();
285 const fvPatchVectorField& psf = bvf[patchi];
287 const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
288 const vectorField& pCf = Cf.boundaryField()[patchi];
292 vectorField psfNei = psf.patchNeighbourField();
294 forAll(pOwner, pFacei)
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;
315 maxFace - vsfOwn, minFace - vsfOwn,
320 else if (psf.fixesValue())
322 forAll(pOwner, pFacei)
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;
343 maxFace - vsfOwn, minFace - vsfOwn,
352 Info<< "gradient limiter for: " << vvf.name()
353 << " max = " << gMax(limiter)
354 << " min = " << gMin(limiter)
355 << " average: " << gAverage(limiter) << endl;
358 g.internalField() *= limiter;
359 g.correctBoundaryConditions();
360 gaussGrad<vector>::correctBoundaryConditions(vvf, g);
366 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
368 } // End namespace fv
370 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
372 } // End namespace Foam
374 // ************************************************************************* //