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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "numericFlux.H"
28 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
30 // Construct from components
31 template<class Flux, class Limiter>
32 Foam::numericFlux<Flux, Limiter>::numericFlux
34 const volScalarField& p,
35 const volVectorField& U,
36 const volScalarField& T,
40 numericFluxBase<Flux>(),
51 mesh_.time().timeName(),
56 (linearInterpolate(thermo_.rho()*U_) & mesh_.Sf())
63 mesh_.time().timeName(),
68 rhoFlux_*linearInterpolate(U_)
75 mesh_.time().timeName(),
80 rhoFlux_*linearInterpolate(thermo.Cv()*T_ + 0.5*magSqr(U_))
82 gradP_(fvc::grad(p_)),
83 gradU_(fvc::grad(U_)),
88 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
90 template<class Flux, class Limiter>
91 void Foam::numericFlux<Flux, Limiter>::computeFlux()
93 // Get face-to-cell addressing: face area point from owner to neighbour
94 const unallocLabelList& owner = mesh_.owner();
95 const unallocLabelList& neighbour = mesh_.neighbour();
97 // Get the face area vector
98 const surfaceVectorField& Sf = mesh_.Sf();
99 const surfaceScalarField& magSf = mesh_.magSf();
101 const volVectorField& cellCentre = mesh_.C();
102 const surfaceVectorField& faceCentre = mesh_.Cf();
105 const volScalarField Cv = thermo_.Cv();
106 const volScalarField R = thermo_.Cp() - Cv;
108 gradP_ = fvc::grad(p_);
109 gradP_.correctBoundaryConditions();
111 gradU_ = fvc::grad(U_);
112 gradU_.correctBoundaryConditions();
114 gradT_ = fvc::grad(T_);
115 gradT_.correctBoundaryConditions();
117 MDLimiter<scalar, Limiter> scalarPLimiter
123 MDLimiter<vector, Limiter> vectorULimiter
129 MDLimiter<scalar, Limiter> scalarTLimiter
136 const volScalarField& pLimiter = scalarPLimiter.phiLimiter();
137 const volVectorField& ULimiter = vectorULimiter.phiLimiter();
138 const volScalarField& TLimiter = scalarTLimiter.phiLimiter();
140 // Calculate fluxes at internal faces
141 forAll (owner, faceI)
143 const label own = owner[faceI];
144 const label nei = neighbour[faceI];
146 const vector deltaRLeft = faceCentre[faceI] - cellCentre[own];
147 const vector deltaRRight = faceCentre[faceI] - cellCentre[nei];
149 // calculate fluxes with reconstructed primitive variables at faces
155 p_[own] + pLimiter[own]*(deltaRLeft & gradP_[own]),
156 p_[nei] + pLimiter[nei]*(deltaRRight & gradP_[nei]),
157 U_[own] + cmptMultiply(ULimiter[own], (deltaRLeft & gradU_[own])),
158 U_[nei] + cmptMultiply(ULimiter[nei], (deltaRRight & gradU_[nei])),
159 T_[own] + TLimiter[own]*(deltaRLeft & gradT_[own]),
160 T_[nei] + TLimiter[nei]*(deltaRRight & gradT_[nei]),
170 // Update boundary field and values
171 forAll (rhoFlux_.boundaryField(), patchi)
173 const fvPatch& curPatch = p_.boundaryField()[patchi].patch();
176 fvsPatchScalarField& pRhoFlux = rhoFlux_.boundaryField()[patchi];
177 fvsPatchVectorField& pRhoUFlux = rhoUFlux_.boundaryField()[patchi];
178 fvsPatchScalarField& pRhoEFlux = rhoEFlux_.boundaryField()[patchi];
181 const fvPatchScalarField& pp = p_.boundaryField()[patchi];
182 const vectorField& pU = U_.boundaryField()[patchi];
183 const scalarField& pT = T_.boundaryField()[patchi];
185 const scalarField& pCv = Cv.boundaryField()[patchi];
186 const scalarField& pR = R.boundaryField()[patchi];
189 const fvPatchVectorField& pGradP = gradP_.boundaryField()[patchi];
190 const fvPatchTensorField& pGradU = gradU_.boundaryField()[patchi];
191 const fvPatchVectorField& pGradT = gradT_.boundaryField()[patchi];
194 const fvPatchScalarField& pPatchLim = pLimiter.boundaryField()[patchi];
195 const fvPatchVectorField& UPatchLim = ULimiter.boundaryField()[patchi];
196 const fvPatchScalarField& TPatchLim = TLimiter.boundaryField()[patchi];
199 const fvsPatchVectorField& pSf = Sf.boundaryField()[patchi];
200 const fvsPatchScalarField& pMagSf = magSf.boundaryField()[patchi];
205 const scalarField ppLeft =
206 p_.boundaryField()[patchi].patchInternalField();
208 const scalarField ppRight =
209 p_.boundaryField()[patchi].patchNeighbourField();
211 const vectorField pULeft =
212 U_.boundaryField()[patchi].patchInternalField();
214 const vectorField pURight =
215 U_.boundaryField()[patchi].patchNeighbourField();
217 const scalarField pTLeft =
218 T_.boundaryField()[patchi].patchInternalField();
220 const scalarField pTRight =
221 T_.boundaryField()[patchi].patchNeighbourField();
224 const vectorField pgradPLeft = pGradP.patchInternalField();
225 const vectorField pgradPRight = pGradP.patchNeighbourField();
227 const tensorField pgradULeft = pGradU.patchInternalField();
228 const tensorField pgradURight = pGradU.patchNeighbourField();
230 const vectorField pgradTLeft = pGradT.patchInternalField();
231 const vectorField pgradTRight = pGradT.patchNeighbourField();
233 // Geometry: call the raw cell-to-face vector by calling
234 // the base patch (cell-to-face) delta coefficient
235 // Work out the right delta from the cell-to-cell delta
236 // across the coupled patch and left delta
237 vectorField pDeltaRLeft = curPatch.fvPatch::delta();
238 vectorField pDdeltaRRight = pDeltaRLeft - curPatch.delta();
242 const scalarField ppLimiterLeft = pPatchLim.patchInternalField();
243 const scalarField ppLimiterRight = pPatchLim.patchNeighbourField();
245 const vectorField pULimiterLeft = UPatchLim.patchInternalField();
246 const vectorField pULimiterRight = UPatchLim.patchNeighbourField();
248 const scalarField pTLimiterLeft = TPatchLim.patchInternalField();
249 const scalarField pTLimiterRight = TPatchLim.patchNeighbourField();
260 + ppLimiterLeft[facei]*
261 (pDeltaRLeft[facei] & pgradPLeft[facei]),
264 + ppLimiterRight[facei]*
265 (pDdeltaRRight[facei] & pgradPRight[facei]),
270 pULimiterLeft[facei],
271 pDeltaRLeft[facei] & pgradULeft[facei]
277 pULimiterRight[facei],
278 pDdeltaRRight[facei] & pgradURight[facei]
282 + pTLimiterLeft[facei]*
283 (pDeltaRLeft[facei] & pgradTLeft[facei]),
286 + pTLimiterRight[facei]*
287 (pDdeltaRRight[facei] & pgradTRight[facei]),
327 // ************************************************************************* //