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 \*---------------------------------------------------------------------------*/
28 #include "surfaceFields.H"
29 #include "volFields.H"
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34 template<class Form, class ExtendedStencil, class Polynomial>
35 Foam::FitData<Form, ExtendedStencil, Polynomial>::FitData
38 const ExtendedStencil& stencil,
39 const bool linearCorrection,
40 const scalar linearLimitFactor,
41 const scalar centralWeight
44 MeshObject<fvMesh, Form>(mesh),
46 linearCorrection_(linearCorrection),
47 linearLimitFactor_(linearLimitFactor),
48 centralWeight_(centralWeight),
49 # ifdef SPHERICAL_GEOMETRY
52 dim_(mesh.nGeometricD()),
54 minSize_(Polynomial::nTerms(dim_))
57 if (linearLimitFactor <= SMALL || linearLimitFactor > 3)
59 FatalErrorIn("FitData<Polynomial>::FitData(..)")
60 << "linearLimitFactor requested = " << linearLimitFactor
61 << " should be between zero and 3"
67 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
69 template<class FitDataType, class ExtendedStencil, class Polynomial>
70 void Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::findFaceDirs
72 vector& idir, // value changed in return
73 vector& jdir, // value changed in return
74 vector& kdir, // value changed in return
78 const fvMesh& mesh = this->mesh();
80 idir = mesh.faceAreas()[facei];
83 # ifndef SPHERICAL_GEOMETRY
84 if (mesh.nGeometricD() <= 2) // find the normal direction
86 if (mesh.geometricD()[0] == -1)
88 kdir = vector(1, 0, 0);
90 else if (mesh.geometricD()[1] == -1)
92 kdir = vector(0, 1, 0);
96 kdir = vector(0, 0, 1);
99 else // 3D so find a direction in the plane of the face
101 const face& f = mesh.faces()[facei];
102 kdir = mesh.points()[f[0]] - mesh.faceCentres()[facei];
105 // Spherical geometry so kdir is the radial direction
106 kdir = mesh.faceCentres()[facei];
109 if (mesh.nGeometricD() == 3)
111 // Remove the idir component from kdir and normalise
112 kdir -= (idir & kdir)*idir;
114 scalar magk = mag(kdir);
118 FatalErrorIn("findFaceDirs(..)") << " calculated kdir = zero"
131 template<class FitDataType, class ExtendedStencil, class Polynomial>
132 void Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::calcFit
135 const List<point>& C,
143 findFaceDirs(idir, jdir, kdir, facei);
145 // Setup the point weights
146 scalarList wts(C.size(), scalar(1));
147 wts[0] = centralWeight_;
148 if (linearCorrection_)
150 wts[1] = centralWeight_;
154 point p0 = this->mesh().faceCentres()[facei];
156 // Info << "Face " << facei << " at " << p0 << " stencil points at:\n"
157 // << C - p0 << endl;
159 // p0 -> p vector in the face-local coordinate system
162 // Local coordinate scaling
165 // Matrix of the polynomial components
166 scalarRectangularMatrix B(C.size(), minSize_, scalar(0));
168 for(label ip = 0; ip < C.size(); ip++)
170 const point& p = C[ip];
172 d.x() = (p - p0)&idir;
173 d.y() = (p - p0)&jdir;
174 # ifndef SPHERICAL_GEOMETRY
175 d.z() = (p - p0)&kdir;
177 d.z() = mag(p) - mag(p0);
182 scale = cmptMax(cmptMag((d)));
185 // Scale the radius vector
188 Polynomial::addCoeffs
197 // Additional weighting for constant and linear terms
198 for(label i = 0; i < B.n(); i++)
205 label stencilSize = C.size();
206 coeffsi.setSize(stencilSize);
208 bool goodFit = false;
209 for(int iIt = 0; iIt < 8 && !goodFit; iIt++)
216 for(label i=0; i<stencilSize; i++)
218 coeffsi[i] = wts[0]*wts[i]*svd.VSinvUt()[0][i];
219 if (mag(coeffsi[i]) > maxCoeff)
221 maxCoeff = mag(coeffsi[i]);
226 if (linearCorrection_)
229 (mag(coeffsi[0] - wLin) < linearLimitFactor_*wLin)
230 && (mag(coeffsi[1] - (1 - wLin)) < linearLimitFactor_*(1 - wLin))
235 // Upwind: weight on face is 1.
237 (mag(coeffsi[0] - 1.0) < linearLimitFactor_*1.0)
241 // if (goodFit && iIt > 0)
243 // Info << "FitData<Polynomial>::calcFit"
244 // << "(const List<point>& C, const label facei" << nl
245 // << "Can now fit face " << facei << " iteration " << iIt
246 // << " with sum of weights " << sum(coeffsi) << nl
247 // << " Weights " << coeffsi << nl
248 // << " Linear weights " << wLin << " " << 1 - wLin << nl
249 // << " sing vals " << svd.S() << endl;
252 if (!goodFit) // (not good fit so increase weight in the centre and weight
253 // for constant and linear terms)
259 // "FitData<Polynomial>::calcFit"
260 // "(const List<point>& C, const label facei"
261 // ) << "Cannot fit face " << facei << " iteration " << iIt
262 // << " with sum of weights " << sum(coeffsi) << nl
263 // << " Weights " << coeffsi << nl
264 // << " Linear weights " << wLin << " " << 1 - wLin << nl
265 // << " sing vals " << svd.S() << endl;
269 if (linearCorrection_)
274 for(label j = 0; j < B.m(); j++)
280 for(label i = 0; i < B.n(); i++)
290 if (linearCorrection_)
292 // Remove the uncorrected linear coefficients
294 coeffsi[1] -= 1 - wLin;
298 // Remove the uncorrected upwind coefficients
308 "FitData<Polynomial>::calcFit(..)"
309 ) << "Could not fit face " << facei
310 << " Weights = " << coeffsi
311 << ", reverting to linear." << nl
312 << " Linear weights " << wLin << " " << 1 - wLin << endl;
320 template<class FitDataType, class ExtendedStencil, class Polynomial>
321 bool Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::movePoints()
327 // ************************************************************************* //