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 "fourthGrad.H"
28 #include "leastSquaresGrad.H"
29 #include "gaussGrad.H"
32 #include "surfaceMesh.H"
33 #include "GeometricField.H"
34 #include "zeroGradientFvPatchField.H"
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
53 typename outerProduct<vector, Type>::type, fvPatchField, volMesh
56 fourthGrad<Type>::grad
58 const GeometricField<Type, fvPatchField, volMesh>& vsf
61 // The fourth-order gradient is calculated in two passes. First,
62 // the standard least-square gradient is assembled. Then, the
63 // fourth-order correction is added to the second-order accurate
64 // gradient to complete the accuracy.
66 typedef typename outerProduct<vector, Type>::type GradType;
68 const fvMesh& mesh = vsf.mesh();
70 // Assemble the second-order least-square gradient
71 // Calculate the second-order least-square gradient
72 tmp<GeometricField<GradType, fvPatchField, volMesh> > tsecondfGrad
73 = leastSquaresGrad<Type>(mesh).grad(vsf);
74 const GeometricField<GradType, fvPatchField, volMesh>& secondfGrad =
77 tmp<GeometricField<GradType, fvPatchField, volMesh> > tfGrad
79 new GeometricField<GradType, fvPatchField, volMesh>
83 "grad("+vsf.name()+')',
92 GeometricField<GradType, fvPatchField, volMesh>& fGrad = tfGrad();
94 const vectorField& C = mesh.C();
96 const surfaceScalarField& lambda = mesh.weights();
98 // Get reference to least square vectors
99 const leastSquaresVectors& lsv = leastSquaresVectors::New(mesh);
100 const surfaceVectorField& ownLs = lsv.pVectors();
101 const surfaceVectorField& neiLs = lsv.nVectors();
103 // owner/neighbour addressing
104 const unallocLabelList& own = mesh.owner();
105 const unallocLabelList& nei = mesh.neighbour();
107 // Assemble the fourth-order gradient
112 Type dDotGradDelta = 0.5*
114 (C[nei[facei]] - C[own[facei]])
115 & (secondfGrad[nei[facei]] - secondfGrad[own[facei]])
118 fGrad[own[facei]] -= lambda[facei]*ownLs[facei]*dDotGradDelta;
119 fGrad[nei[facei]] -= (1.0 - lambda[facei])*neiLs[facei]*dDotGradDelta;
123 forAll(vsf.boundaryField(), patchi)
125 if (secondfGrad.boundaryField()[patchi].coupled())
127 const fvsPatchVectorField& patchOwnLs =
128 ownLs.boundaryField()[patchi];
130 const scalarField& lambdap = lambda.boundaryField()[patchi];
132 // Build the d-vectors
134 mesh.Sf().boundaryField()[patchi]
136 mesh.magSf().boundaryField()[patchi]
137 *mesh.deltaCoeffs().boundaryField()[patchi]
140 if (!mesh.orthogonal())
142 pd -= mesh.correctionVectors().boundaryField()[patchi]
143 /mesh.deltaCoeffs().boundaryField()[patchi];
146 const unallocLabelList& faceCells =
147 fGrad.boundaryField()[patchi].patch().faceCells();
149 Field<GradType> neighbourSecondfGrad =
150 secondfGrad.boundaryField()[patchi].patchNeighbourField();
152 forAll(faceCells, patchFaceI)
154 fGrad[faceCells[patchFaceI]] -=
155 0.5*lambdap[patchFaceI]*patchOwnLs[patchFaceI]
159 neighbourSecondfGrad[patchFaceI]
160 - secondfGrad[faceCells[patchFaceI]]
167 fGrad.correctBoundaryConditions();
168 gaussGrad<Type>::correctBoundaryConditions(vsf, fGrad);
174 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
176 } // End namespace fv
178 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
180 } // End namespace Foam
182 // ************************************************************************* //