1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
5 \\ / A nd | 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/>.
25 Class to create the weighting-factors based on the NVD
26 (Normalised Variable Diagram).
27 The particular differencing scheme class is supplied as a template argument,
28 the weight function of which is called by the weight function of this class
29 for the internal edges as well as edges of coupled patches
30 (e.g. processor-processor patches). The weight function is supplied the
31 central-differencing weighting factor, the edge-flux, the cell and edge
32 gradients (from which the normalised variable distribution may be created)
33 and the cell centre distance.
35 This code organisation is both neat and efficient, allowing for convenient
36 implementation of new schemes to run on parallelised cases.
38 \*---------------------------------------------------------------------------*/
40 #include "areaFields.H"
41 #include "edgeFields.H"
43 #include "coupledFaPatchFields.H"
44 #include "upwindEdgeInterpolation.H"
46 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
51 inline tmp<areaScalarField> limiter(const areaScalarField& phi)
56 inline tmp<areaScalarField> limiter(const areaVectorField& phi)
61 inline tmp<areaScalarField> limiter(const areaTensorField& phi)
67 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
68 //- Return the interpolation weighting factors
70 template<class Type, class NVDweight>
71 tmp<edgeScalarField> faNVDscheme<Type,NVDweight>::weights
73 const GeometricField<Type, faPatchField, areaMesh>& phi
76 const faMesh& mesh = this->mesh();
78 tmp<edgeScalarField> tWeightingFactors
80 new edgeScalarField(mesh.edgeInterpolation::weights())
82 edgeScalarField& weightingFactors = tWeightingFactors();
84 scalarField& weights = weightingFactors.internalField();
86 tmp<areaScalarField> tvf = limiter(phi);
87 const areaScalarField& vf = tvf();
89 areaVectorField gradc(fac::grad(vf));
91 // edgeVectorField d =
93 // /(mesh.magLe()*mesh.edgeInterpolation::deltaCoeffs());
95 // if (!mesh.orthogonal())
98 // mesh.edgeInterpolation::correctionVectors()
99 // /mesh.edgeInterpolation::deltaCoeffs();
102 const unallocLabelList& owner = mesh.owner();
103 const unallocLabelList& neighbour = mesh.neighbour();
104 const vectorField& n = mesh.faceAreaNormals().internalField();
105 const vectorField& c = mesh.areaCentres().internalField();
107 forAll(weights, edge)
109 vector d = vector::zero;
111 if(edgeFlux_[edge] > 0)
113 d = c[neighbour[edge]] - c[owner[edge]];
114 d -= n[owner[edge]]*(n[owner[edge]]&d);
115 d /= mag(d)/mesh.edgeInterpolation::lPN().internalField()[edge];
119 d = c[neighbour[edge]] - c[owner[edge]];
120 d -= n[neighbour[edge]]*(n[neighbour[edge]]&d);
121 d /= mag(d)/mesh.edgeInterpolation::lPN().internalField()[edge];
132 gradc[neighbour[edge]],
138 GeometricField<scalar, faePatchField, edgeMesh>::GeometricBoundaryField&
139 bWeights = weightingFactors.boundaryField();
141 forAll(bWeights, patchI)
143 if (bWeights[patchI].coupled())
145 scalarField& pWeights = bWeights[patchI];
147 const scalarField& pEdgeFlux = edgeFlux_.boundaryField()[patchI];
150 vf.boundaryField()[patchI].patchInternalField();
153 vf.boundaryField()[patchI].patchNeighbourField();
155 vectorField pGradcP =
156 gradc.boundaryField()[patchI].patchInternalField();
158 vectorField pGradcN =
159 gradc.boundaryField()[patchI].patchNeighbourField();
161 vectorField CP = mesh.areaCentres().boundaryField()[patchI]
162 .patchInternalField();
165 mesh.areaCentres().boundaryField()[patchI]
166 .patchNeighbourField();
169 mesh.faceAreaNormals().boundaryField()[patchI]
170 .patchInternalField();
173 mesh.faceAreaNormals().boundaryField()[patchI]
174 .patchNeighbourField();
177 mesh.edgeInterpolation::lPN().boundaryField()[patchI];
179 forAll(pWeights, edgeI)
181 vector d = vector::zero;
183 if(pEdgeFlux[edgeI] > 0)
185 d = CN[edgeI] - CP[edgeI];
186 d -= nP[edgeI]*(nP[edgeI]&d);
187 d /= mag(d)/pLPN[edgeI];
191 d = CN[edgeI] - CP[edgeI];
192 d -= nN[edgeI]*(nN[edgeI]&d);
193 d /= mag(d)/pLPN[edgeI];
211 return tWeightingFactors;
215 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
217 } // End namespace Foam
219 // ************************************************************************* //