initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / finiteVolume / finiteVolume / gradSchemes / limitedGradSchemes / cellMDLimitedGrad / cellMDLimitedGrads.C
blob5a35033428c340220b6474ff4ab407ea1c1ed91f
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
25 \*---------------------------------------------------------------------------*/
27 #include "cellMDLimitedGrad.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(cellMDLimitedGrad)
49 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
51 template<>
52 tmp<volVectorField> cellMDLimitedGrad<scalar>::grad
54     const volScalarField& vsf
55 ) const
57     const fvMesh& mesh = vsf.mesh();
59     tmp<volVectorField> tGrad = basicGradScheme_().grad(vsf);
61     if (k_ < SMALL)
62     {
63         return tGrad;
64     }
66     volVectorField& g = tGrad();
68     const unallocLabelList& owner = mesh.owner();
69     const unallocLabelList& neighbour = mesh.neighbour();
71     const volVectorField& C = mesh.C();
72     const surfaceVectorField& Cf = mesh.Cf();
74     scalarField maxVsf(vsf.internalField());
75     scalarField minVsf(vsf.internalField());
77     forAll(owner, facei)
78     {
79         label own = owner[facei];
80         label nei = neighbour[facei];
82         scalar vsfOwn = vsf[own];
83         scalar vsfNei = vsf[nei];
85         maxVsf[own] = max(maxVsf[own], vsfNei);
86         minVsf[own] = min(minVsf[own], vsfNei);
88         maxVsf[nei] = max(maxVsf[nei], vsfOwn);
89         minVsf[nei] = min(minVsf[nei], vsfOwn);
90     }
93     const volScalarField::GeometricBoundaryField& bsf = vsf.boundaryField();
95     forAll(bsf, patchi)
96     {
97         const fvPatchScalarField& psf = bsf[patchi];
99         const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
101         if (psf.coupled())
102         {
103             scalarField psfNei = psf.patchNeighbourField();
105             forAll(pOwner, pFacei)
106             {
107                 label own = pOwner[pFacei];
108                 scalar vsfNei = psfNei[pFacei];
110                 maxVsf[own] = max(maxVsf[own], vsfNei);
111                 minVsf[own] = min(minVsf[own], vsfNei);
112             }
113         }
114         else
115         {
116             forAll(pOwner, pFacei)
117             {
118                 label own = pOwner[pFacei];
119                 scalar vsfNei = psf[pFacei];
121                 maxVsf[own] = max(maxVsf[own], vsfNei);
122                 minVsf[own] = min(minVsf[own], vsfNei);
123             }
124         }
125     }
127     maxVsf -= vsf;
128     minVsf -= vsf;
130     if (k_ < 1.0)
131     {
132         scalarField maxMinVsf = (1.0/k_ - 1.0)*(maxVsf - minVsf);
133         maxVsf += maxMinVsf;
134         minVsf -= maxMinVsf;
136         //maxVsf *= 1.0/k_;
137         //minVsf *= 1.0/k_;
138     }
141     forAll(owner, facei)
142     {
143         label own = owner[facei];
144         label nei = neighbour[facei];
146         // owner side
147         limitFace
148         (
149             g[own],
150             maxVsf[own],
151             minVsf[own],
152             Cf[facei] - C[own]
153         );
155         // neighbour side
156         limitFace
157         (
158             g[nei],
159             maxVsf[nei],
160             minVsf[nei],
161             Cf[facei] - C[nei]
162         );
163     }
166     forAll(bsf, patchi)
167     {
168         const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
169         const vectorField& pCf = Cf.boundaryField()[patchi];
171         forAll(pOwner, pFacei)
172         {
173             label own = pOwner[pFacei];
175             limitFace
176             (
177                 g[own],
178                 maxVsf[own],
179                 minVsf[own],
180                 pCf[pFacei] - C[own]
181             );
182         }
183     }
185     g.correctBoundaryConditions();
186     gaussGrad<scalar>::correctBoundaryConditions(vsf, g);
188     return tGrad;
192 template<>
193 tmp<volTensorField> cellMDLimitedGrad<vector>::grad
195     const volVectorField& vsf
196 ) const
198     const fvMesh& mesh = vsf.mesh();
200     tmp<volTensorField> tGrad = basicGradScheme_().grad(vsf);
202     if (k_ < SMALL)
203     {
204         return tGrad;
205     }
207     volTensorField& g = tGrad();
209     const unallocLabelList& owner = mesh.owner();
210     const unallocLabelList& neighbour = mesh.neighbour();
212     const volVectorField& C = mesh.C();
213     const surfaceVectorField& Cf = mesh.Cf();
215     vectorField maxVsf(vsf.internalField());
216     vectorField minVsf(vsf.internalField());
218     forAll(owner, facei)
219     {
220         label own = owner[facei];
221         label nei = neighbour[facei];
223         const vector& vsfOwn = vsf[own];
224         const vector& vsfNei = vsf[nei];
226         maxVsf[own] = max(maxVsf[own], vsfNei);
227         minVsf[own] = min(minVsf[own], vsfNei);
229         maxVsf[nei] = max(maxVsf[nei], vsfOwn);
230         minVsf[nei] = min(minVsf[nei], vsfOwn);
231     }
234     const volVectorField::GeometricBoundaryField& bsf = vsf.boundaryField();
236     forAll(bsf, patchi)
237     {
238         const fvPatchVectorField& psf = bsf[patchi];
239         const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
241         if (psf.coupled())
242         {
243             vectorField psfNei = psf.patchNeighbourField();
245             forAll(pOwner, pFacei)
246             {
247                 label own = pOwner[pFacei];
248                 const vector& vsfNei = psfNei[pFacei];
250                 maxVsf[own] = max(maxVsf[own], vsfNei);
251                 minVsf[own] = min(minVsf[own], vsfNei);
252             }
253         }
254         else
255         {
256             forAll(pOwner, pFacei)
257             {
258                 label own = pOwner[pFacei];
259                 const vector& vsfNei = psf[pFacei];
261                 maxVsf[own] = max(maxVsf[own], vsfNei);
262                 minVsf[own] = min(minVsf[own], vsfNei);
263             }
264         }
265     }
267     maxVsf -= vsf;
268     minVsf -= vsf;
270     if (k_ < 1.0)
271     {
272         vectorField maxMinVsf = (1.0/k_ - 1.0)*(maxVsf - minVsf);
273         maxVsf += maxMinVsf;
274         minVsf -= maxMinVsf;
276         //maxVsf *= 1.0/k_;
277         //minVsf *= 1.0/k_;
278     }
281     forAll(owner, facei)
282     {
283         label own = owner[facei];
284         label nei = neighbour[facei];
286         // owner side
287         limitFace
288         (
289             g[own],
290             maxVsf[own],
291             minVsf[own],
292             Cf[facei] - C[own]
293         );
295         // neighbour side
296         limitFace
297         (
298             g[nei],
299             maxVsf[nei],
300             minVsf[nei],
301             Cf[facei] - C[nei]
302         );
303     }
306     forAll(bsf, patchi)
307     {
308         const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
309         const vectorField& pCf = Cf.boundaryField()[patchi];
311         forAll(pOwner, pFacei)
312         {
313             label own = pOwner[pFacei];
315             limitFace
316             (
317                 g[own],
318                 maxVsf[own],
319                 minVsf[own],
320                 pCf[pFacei] - C[own]
321             );
322         }
323     }
325     g.correctBoundaryConditions();
326     gaussGrad<vector>::correctBoundaryConditions(vsf, g);
328     return tGrad;
332 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
334 } // End namespace fv
336 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
338 } // End namespace Foam
340 // ************************************************************************* //