CentredFitSnGradData.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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
19  for more details.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "CentredFitSnGradData.H"
27 #include "surfaceFields.H"
28 #include "SVD.H"
30 
31 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
32 
33 template<class Polynomial>
35 (
36  const fvMesh& mesh,
37  const extendedCentredCellToFaceStencil& stencil,
38  const scalar linearLimitFactor,
39  const scalar centralWeight
40 )
41 :
42  FitData
43  <
47  >
48  (
49  mesh, stencil, true, linearLimitFactor, centralWeight
50  ),
51  coeffs_(mesh.nFaces())
52 {
53  if (debug)
54  {
55  Info<< "Contructing CentredFitSnGradData<Polynomial>" << endl;
56  }
57 
58  calcFit();
59 
60  if (debug)
61  {
62  Info<< "CentredFitSnGradData<Polynomial>::CentredFitSnGradData() :"
63  << "Finished constructing polynomialFit data"
64  << endl;
65  }
66 }
67 
68 
69 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
70 
71 template<class Polynomial>
73 (
74  scalarList& coeffsi,
75  const List<point>& C,
76  const scalar wLin,
77  const scalar deltaCoeff,
78  const label facei
79 )
80 {
81  vector idir(1,0,0);
82  vector jdir(0,1,0);
83  vector kdir(0,0,1);
84  this->findFaceDirs(idir, jdir, kdir, facei);
85 
86  // Setup the point weights
87  scalarList wts(C.size(), scalar(1));
88  wts[0] = this->centralWeight();
89  wts[1] = this->centralWeight();
90 
91  // Reference point
92  point p0 = this->mesh().faceCentres()[facei];
93 
94  // p0 -> p vector in the face-local coordinate system
95  vector d;
96 
97  // Local coordinate scaling
98  scalar scale = 1;
99 
100  // Matrix of the polynomial components
101  scalarRectangularMatrix B(C.size(), this->minSize(), scalar(0));
102 
103  forAll(C, ip)
104  {
105  const point& p = C[ip];
106  const vector p0p = p - p0;
107 
108  d.x() = p0p & idir;
109  d.y() = p0p & jdir;
110  d.z() = p0p & kdir;
111 
112  if (ip == 0)
113  {
114  scale = cmptMax(cmptMag((d)));
115  }
116 
117  // Scale the radius vector
118  d /= scale;
119 
120  Polynomial::addCoeffs(B[ip], d, wts[ip], this->dim());
121  }
122 
123  // Additional weighting for constant and linear terms
124  for (label i = 0; i < B.n(); i++)
125  {
126  B[i][0] *= wts[0];
127  B[i][1] *= wts[0];
128  }
129 
130  // Set the fit
131  label stencilSize = C.size();
132  coeffsi.setSize(stencilSize);
133 
134  bool goodFit = false;
135  for (int iIt = 0; iIt < 8 && !goodFit; iIt++)
136  {
137  SVD svd(B, SMALL);
138 
139  for (label i=0; i<stencilSize; i++)
140  {
141  coeffsi[i] = wts[1]*wts[i]*svd.VSinvUt()[1][i]/scale;
142  }
143 
144  goodFit =
145  (
146  mag(wts[0]*wts[0]*svd.VSinvUt()[0][0] - wLin)
147  < this->linearLimitFactor()*wLin)
148  && (mag(wts[0]*wts[1]*svd.VSinvUt()[0][1] - (1 - wLin)
149  ) < this->linearLimitFactor()*(1 - wLin))
150  && coeffsi[0] < 0 && coeffsi[1] > 0
151  && mag(coeffsi[0] + deltaCoeff) < 0.5*deltaCoeff
152  && mag(coeffsi[1] - deltaCoeff) < 0.5*deltaCoeff;
153 
154  if (!goodFit)
155  {
156  // (not good fit so increase weight in the centre and weight
157  // for constant and linear terms)
158 
160  << "Cannot fit face " << facei << " iteration " << iIt
161  << " with sum of weights " << sum(coeffsi) << nl
162  << " Weights " << coeffsi << nl
163  << " Linear weights " << wLin << " " << 1 - wLin << nl
164  << " deltaCoeff " << deltaCoeff << nl
165  << " sing vals " << svd.S() << nl
166  << "Components of goodFit:\n"
167  << " wts[0]*wts[0]*svd.VSinvUt()[0][0] = "
168  << wts[0]*wts[0]*svd.VSinvUt()[0][0] << nl
169  << " wts[0]*wts[1]*svd.VSinvUt()[0][1] = "
170  << wts[0]*wts[1]*svd.VSinvUt()[0][1]
171  << " dim = " << this->dim() << endl;
172 
173  wts[0] *= 10;
174  wts[1] *= 10;
175 
176  for (label j = 0; j < B.m(); j++)
177  {
178  B[0][j] *= 10;
179  B[1][j] *= 10;
180  }
181 
182  for (label i = 0; i < B.n(); i++)
183  {
184  B[i][0] *= 10;
185  B[i][1] *= 10;
186  }
187  }
188  }
189 
190  if (goodFit)
191  {
192  // Remove the uncorrected coefficients
193  coeffsi[0] += deltaCoeff;
194  coeffsi[1] -= deltaCoeff;
195  }
196  else
197  {
199  << "Could not fit face " << facei
200  << " Coefficients = " << coeffsi
201  << ", reverting to uncorrected." << endl;
202 
203  coeffsi = 0;
204  }
205 }
206 
207 
208 template<class Polynomial>
210 {
211  const fvMesh& mesh = this->mesh();
212 
213  // Get the cell/face centres in stencil order.
214  // Centred face stencils no good for triangles or tets.
215  // Need bigger stencils
216  List<List<point> > stencilPoints(mesh.nFaces());
217  this->stencil().collectData(mesh.C(), stencilPoints);
218 
219  // find the fit coefficients for every face in the mesh
220 
221  const surfaceScalarField& w = mesh.surfaceInterpolation::weights();
222  const surfaceScalarField& dC = mesh.nonOrthDeltaCoeffs();
223 
224  for (label facei = 0; facei < mesh.nInternalFaces(); facei++)
225  {
226  calcFit
227  (
228  coeffs_[facei],
229  stencilPoints[facei],
230  w[facei],
231  dC[facei],
232  facei
233  );
234  }
235 
236  const surfaceScalarField::GeometricBoundaryField& bw = w.boundaryField();
238 
239  forAll(bw, patchi)
240  {
241  const fvsPatchScalarField& pw = bw[patchi];
242  const fvsPatchScalarField& pdC = bdC[patchi];
243 
244  if (pw.coupled())
245  {
246  label facei = pw.patch().start();
247 
248  forAll(pw, i)
249  {
250  calcFit
251  (
252  coeffs_[facei],
253  stencilPoints[facei],
254  pw[i],
255  pdC[i],
256  facei
257  );
258  facei++;
259  }
260  }
261  }
262 }
263 
264 
265 // ************************************************************************* //
Foam::Matrix::m
label m() const
Return the number of columns.
Definition: MatrixI.H:63
Foam::FitData
Data for the upwinded and centred polynomial fit interpolation schemes. The linearCorrection_ determi...
Definition: FitData.H:54
w
volScalarField w(IOobject("w", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE), mesh, dimensionedScalar("w", dimensionSet(0, 0, 0, 0, 0, 0, 0), 0.0))
p
p
Definition: pEqn.H:62
SVD.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::extendedCentredCellToFaceStencil
Definition: extendedCentredCellToFaceStencil.H:49
Foam::fvsPatchField
An abstract base class with a fat-interface to all derived classes covering all possible ways in whic...
Definition: fvsPatchField.H:65
Foam::GeometricField::boundaryField
GeometricBoundaryField & boundaryField()
Return reference to GeometricBoundaryField.
Definition: GeometricField.C:735
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
surfaceFields.H
Foam::surfaceFields.
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::Matrix::n
label n() const
Return the number of rows.
Definition: MatrixI.H:56
Foam::CentredFitSnGradData::CentredFitSnGradData
CentredFitSnGradData(const fvMesh &mesh, const extendedCentredCellToFaceStencil &stencil, const scalar linearLimitFactor, const scalar centralWeight)
Construct from components.
Definition: CentredFitSnGradData.C:35
CentredFitSnGradData.H
Foam::cmptMag
void cmptMag(FieldField< Field, Type > &cf, const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:359
Foam::cmptMax
void cmptMax(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:224
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
Foam::RectangularMatrix< scalar >
Foam::Vector::x
const Cmpt & x() const
Definition: VectorI.H:65
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
extendedCentredCellToFaceStencil.H
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Foam::CentredFitSnGradData
Data for centred fit snGrad schemes.
Definition: CentredFitSnGradData.H:51
Foam::Vector::z
const Cmpt & z() const
Definition: VectorI.H:77
Foam::SVD::S
const scalarDiagonalMatrix & S() const
Return the singular values.
Definition: SVDI.H:47
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::Polynomial
Polynomial templated on size (order):
Definition: Polynomial.H:63
Foam::SVD::VSinvUt
const scalarRectangularMatrix & VSinvUt() const
Return VSinvUt (the pseudo inverse)
Definition: SVDI.H:52
Foam::fvsPatchField::patch
const fvPatch & patch() const
Return patch.
Definition: fvsPatchField.H:278
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::SVD
Singular value decomposition of a rectangular matrix.
Definition: SVD.H:52
patchi
label patchi
Definition: getPatchFieldScalar.H:1
Foam::fvPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: fvPatch.H:155
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:333
Foam::Vector::y
const Cmpt & y() const
Definition: VectorI.H:71
Foam::C
Graphite solid properties.
Definition: C.H:57
Foam::GeometricField
Generic GeometricField class.
Definition: surfaceFieldsFwd.H:52
Foam::CentredFitSnGradData::calcFit
void calcFit()
Calculate the fit for all the faces.
Definition: CentredFitSnGradData.C:209
Foam::fvsPatchField::coupled
virtual bool coupled() const
Return true if this patch field is coupled.
Definition: fvsPatchField.H:308
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:259
Foam::GeometricField::GeometricBoundaryField
Definition: GeometricField.H:105