1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2010 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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
27 #include "surfaceFields.H"
28 #include "volFields.H"
31 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 template<class Form, class ExtendedStencil, class Polynomial>
34 Foam::FitData<Form, ExtendedStencil, Polynomial>::FitData
37 const ExtendedStencil& stencil,
38 const bool linearCorrection,
39 const scalar linearLimitFactor,
40 const scalar centralWeight
43 MeshObject<fvMesh, Form>(mesh),
45 linearCorrection_(linearCorrection),
46 linearLimitFactor_(linearLimitFactor),
47 centralWeight_(centralWeight),
48 # ifdef SPHERICAL_GEOMETRY
51 dim_(mesh.nGeometricD()),
53 minSize_(Polynomial::nTerms(dim_))
56 if (linearLimitFactor <= SMALL || linearLimitFactor > 3)
58 FatalErrorIn("FitData<Polynomial>::FitData(..)")
59 << "linearLimitFactor requested = " << linearLimitFactor
60 << " should be between zero and 3"
66 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
68 template<class FitDataType, class ExtendedStencil, class Polynomial>
69 void Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::findFaceDirs
71 vector& idir, // value changed in return
72 vector& jdir, // value changed in return
73 vector& kdir, // value changed in return
77 const fvMesh& mesh = this->mesh();
79 idir = mesh.faceAreas()[facei];
82 # ifndef SPHERICAL_GEOMETRY
83 if (mesh.nGeometricD() <= 2) // find the normal direction
85 if (mesh.geometricD()[0] == -1)
87 kdir = vector(1, 0, 0);
89 else if (mesh.geometricD()[1] == -1)
91 kdir = vector(0, 1, 0);
95 kdir = vector(0, 0, 1);
98 else // 3D so find a direction in the plane of the face
100 const face& f = mesh.faces()[facei];
101 kdir = mesh.points()[f[0]] - mesh.faceCentres()[facei];
104 // Spherical geometry so kdir is the radial direction
105 kdir = mesh.faceCentres()[facei];
108 if (mesh.nGeometricD() == 3)
110 // Remove the idir component from kdir and normalise
111 kdir -= (idir & kdir)*idir;
113 scalar magk = mag(kdir);
117 FatalErrorIn("findFaceDirs(..)") << " calculated kdir = zero"
130 template<class FitDataType, class ExtendedStencil, class Polynomial>
131 void Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::calcFit
134 const List<point>& C,
142 findFaceDirs(idir, jdir, kdir, facei);
144 // Setup the point weights
145 scalarList wts(C.size(), scalar(1));
146 wts[0] = centralWeight_;
147 if (linearCorrection_)
149 wts[1] = centralWeight_;
153 point p0 = this->mesh().faceCentres()[facei];
155 // Info<< "Face " << facei << " at " << p0 << " stencil points at:\n"
156 // << C - p0 << endl;
158 // p0 -> p vector in the face-local coordinate system
161 // Local coordinate scaling
164 // Matrix of the polynomial components
165 scalarRectangularMatrix B(C.size(), minSize_, scalar(0));
169 const point& p = C[ip];
171 d.x() = (p - p0)&idir;
172 d.y() = (p - p0)&jdir;
173 # ifndef SPHERICAL_GEOMETRY
174 d.z() = (p - p0)&kdir;
176 d.z() = mag(p) - mag(p0);
181 scale = cmptMax(cmptMag((d)));
184 // Scale the radius vector
187 Polynomial::addCoeffs
196 // Additional weighting for constant and linear terms
197 for (label i = 0; i < B.n(); i++)
204 label stencilSize = C.size();
205 coeffsi.setSize(stencilSize);
207 bool goodFit = false;
208 for (int iIt = 0; iIt < 8 && !goodFit; iIt++)
215 for (label i=0; i<stencilSize; i++)
217 coeffsi[i] = wts[0]*wts[i]*svd.VSinvUt()[0][i];
218 if (mag(coeffsi[i]) > maxCoeff)
220 maxCoeff = mag(coeffsi[i]);
225 if (linearCorrection_)
228 (mag(coeffsi[0] - wLin) < linearLimitFactor_*wLin)
229 && (mag(coeffsi[1] - (1 - wLin)) < linearLimitFactor_*(1 - wLin))
234 // Upwind: weight on face is 1.
236 (mag(coeffsi[0] - 1.0) < linearLimitFactor_*1.0)
240 // if (goodFit && iIt > 0)
242 // Info<< "FitData<Polynomial>::calcFit"
243 // << "(const List<point>& C, const label facei" << nl
244 // << "Can now fit face " << facei << " iteration " << iIt
245 // << " with sum of weights " << sum(coeffsi) << nl
246 // << " Weights " << coeffsi << nl
247 // << " Linear weights " << wLin << " " << 1 - wLin << nl
248 // << " sing vals " << svd.S() << endl;
251 if (!goodFit) // (not good fit so increase weight in the centre and
252 // weight for constant and linear terms)
258 // "FitData<Polynomial>::calcFit"
259 // "(const List<point>& C, const label facei"
260 // ) << "Cannot fit face " << facei << " iteration " << iIt
261 // << " with sum of weights " << sum(coeffsi) << nl
262 // << " Weights " << coeffsi << nl
263 // << " Linear weights " << wLin << " " << 1 - wLin << nl
264 // << " sing vals " << svd.S() << endl;
268 if (linearCorrection_)
273 for (label j = 0; j < B.m(); j++)
279 for (label i = 0; i < B.n(); i++)
289 if (linearCorrection_)
291 // Remove the uncorrected linear coefficients
293 coeffsi[1] -= 1 - wLin;
297 // Remove the uncorrected upwind coefficients
307 "FitData<Polynomial>::calcFit(..)"
308 ) << "Could not fit face " << facei
309 << " Weights = " << coeffsi
310 << ", reverting to linear." << nl
311 << " Linear weights " << wLin << " " << 1 - wLin << endl;
319 template<class FitDataType, class ExtendedStencil, class Polynomial>
320 bool Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::movePoints()
326 // ************************************************************************* //