1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
28 Multidimensional limiter for density based solver
32 Updated by Hrvoje Jasak
34 \*---------------------------------------------------------------------------*/
39 #include "volFieldsFwd.H"
40 #include "surfaceFieldsFwd.H"
41 #include "BarthJespersenLimiter.H"
42 #include "VenkatakrishnanLimiter.H"
47 /*---------------------------------------------------------------------------*\
48 Class MDLimiter Declaration
49 \*---------------------------------------------------------------------------*/
54 typename LimiterFunctionType
62 typedef Field<Type> FieldType;
63 typedef GeometricField<Type, fvPatchField, volMesh> GeoFieldType;
65 typedef Field<typename outerProduct<vector, Type>::type> GradFieldType;
66 typedef GeometricField
68 typename outerProduct<vector, Type>::type,
78 //- Reference to the mesh
82 const GeoFieldType& phi_;
85 const GeoGradFieldType& gradPhi_;
88 GeoFieldType phiLimiter_;
95 //- Construct from field and gradient field
98 const GeoFieldType& phi,
99 const GeoGradFieldType& gradPhi
110 mesh_.time().timeName(),
116 dimensioned<Type>("pLimiter", dimless, pTraits<Type>::one)
119 // Collect min and max values from neighbourhood
120 GeoFieldType phiMinValue
126 GeoFieldType phiMaxValue
132 const unallocLabelList& owner = mesh_.owner();
133 const unallocLabelList& neighbour = mesh_.neighbour();
135 Field<Type>& phiMinIn = phiMinValue.internalField();
136 Field<Type>& phiMaxIn = phiMaxValue.internalField();
138 forAll (owner, faceI)
140 const label& own = owner[faceI];
141 const label& nei = neighbour[faceI];
144 phiMinIn[own] = min(phiMinIn[own], phi_[nei]);
145 phiMinIn[nei] = min(phiMinIn[nei], phi_[own]);
148 phiMaxIn[own] = max(phiMaxIn[own], phi_[nei]);
149 phiMaxIn[nei] = max(phiMaxIn[nei], phi_[own]);
152 // Coupled boundaries
153 forAll (phi.boundaryField(), patchI)
155 if (phi.boundaryField()[patchI].coupled())
157 const Field<Type> pNei =
158 phi.boundaryField()[patchI].patchNeighbourField();
160 const labelList& fc =
161 phi.boundaryField()[patchI].patch().faceCells();
165 const label& curFC = fc[faceI];
169 min(phiMinIn[curFC], pNei[faceI]);
173 max(phiMaxIn[curFC], pNei[faceI]);
180 // Get geometrical information
182 const DimensionedField<scalar, volMesh>& cellVolume = mesh_.V();
183 const volVectorField& cellCentre = mesh_.C();
184 const surfaceVectorField& faceCentre = mesh_.Cf();
186 // Create limiter function
187 LimiterFunctionType limitFunction;
189 FieldType& phiLimiterIn = phiLimiter_.internalField();
191 const GradFieldType& gradPhiIn = gradPhi.internalField();
193 // Compute limiter values, internal faces
196 scalar upwindFlux = 1;
198 forAll (owner, faceI)
200 const label& own = owner[faceI];
201 const label& nei = neighbour[faceI];
203 vector deltaRLeft = faceCentre[faceI] - cellCentre[own];
204 vector deltaRRight = faceCentre[faceI] - cellCentre[nei];
206 Type phiOwnerLimiter = limitFunction.limiter
210 phiMaxIn[own] - phi_[own],
211 phiMinIn[own] - phi_[own],
217 Type phiNeighbourLimiter = limitFunction.limiter
221 phiMaxIn[nei] - phi_[nei],
222 phiMinIn[nei] - phi_[nei],
228 // find minimal limiter value in each cell
230 min(phiLimiterIn[own], phiOwnerLimiter);
233 min(phiLimiterIn[nei], phiNeighbourLimiter);
236 // Coupled boundaries
237 forAll (phi.boundaryField(), patchI)
239 if (phi.boundaryField()[patchI].coupled())
242 const fvPatch& p = phi.boundaryField()[patchI].patch();
244 const FieldType pNei =
245 phi.boundaryField()[patchI].patchNeighbourField();
247 const labelList& fc = p.faceCells();
249 const vectorField deltaR = p.Cf() - p.Cn();
252 const GradFieldType gradPhiLeft =
253 gradPhi.boundaryField()[patchI].patchInternalField();
255 const GradFieldType gradPhiRight =
256 gradPhi.boundaryField()[patchI].patchNeighbourField();
260 const label& curFC = fc[faceI];
262 Type phiFCLimiter = limitFunction.limiter
266 phiMaxIn[curFC] - phi_[curFC],
267 phiMinIn[curFC] - phi_[curFC],
273 // Find minimal limiter value in each cell
274 phiLimiterIn[curFC] =
275 min(phiLimiterIn[curFC], phiFCLimiter);
280 // Do parallel communication to correct limiter on
281 // coupled boundaries
282 phiLimiter_.correctBoundaryConditions();
286 // Destructor - default
292 const GeoFieldType& phiLimiter() const
299 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
301 } // End namespace Foam
305 // ************************************************************************* //