surfaceInterpolation.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Description
28  Cell to face interpolation scheme. Included in fvMesh.
29 
30 \*---------------------------------------------------------------------------*/
31 
32 #include "fvMesh.H"
33 #include "volFields.H"
34 #include "surfaceFields.H"
35 #include "demandDrivenData.H"
36 #include "coupledFvPatch.H"
37 
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42  defineTypeNameAndDebug(surfaceInterpolation, 0);
43 }
44 
45 
46 // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
47 
49 {
50  deleteDemandDrivenData(weights_);
51  deleteDemandDrivenData(deltaCoeffs_);
52  deleteDemandDrivenData(nonOrthDeltaCoeffs_);
53  deleteDemandDrivenData(nonOrthCorrectionVectors_);
54 }
55 
56 
57 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
58 
60 :
61  mesh_(fvm),
62  weights_(nullptr),
63  deltaCoeffs_(nullptr),
64  nonOrthDeltaCoeffs_(nullptr),
65  nonOrthCorrectionVectors_(nullptr)
66 {}
67 
68 
69 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
70 
72 {
73  clearOut();
74 }
75 
76 
77 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
78 
80 {
81  if (!weights_)
82  {
83  makeWeights();
84  }
85 
86  return (*weights_);
87 }
88 
89 
91 {
92  if (!deltaCoeffs_)
93  {
94  makeDeltaCoeffs();
95  }
96 
97  return (*deltaCoeffs_);
98 }
99 
100 
103 {
104  if (!nonOrthDeltaCoeffs_)
105  {
106  makeNonOrthDeltaCoeffs();
107  }
108 
109  return (*nonOrthDeltaCoeffs_);
110 }
111 
112 
115 {
116  if (!nonOrthCorrectionVectors_)
117  {
118  makeNonOrthCorrectionVectors();
119  }
120 
121  return (*nonOrthCorrectionVectors_);
122 }
123 
124 
126 {
127  deleteDemandDrivenData(weights_);
128  deleteDemandDrivenData(deltaCoeffs_);
129  deleteDemandDrivenData(nonOrthDeltaCoeffs_);
130  deleteDemandDrivenData(nonOrthCorrectionVectors_);
131 
132  return true;
133 }
134 
135 
136 void Foam::surfaceInterpolation::makeWeights() const
137 {
138  if (debug)
139  {
140  Pout<< "surfaceInterpolation::makeWeights() : "
141  << "Constructing weighting factors for face interpolation"
142  << endl;
143  }
144 
145  weights_ = new surfaceScalarField
146  (
147  IOobject
148  (
149  "weights",
150  mesh_.pointsInstance(),
151  mesh_,
154  false // Do not register
155  ),
156  mesh_,
157  dimless
158  );
159  surfaceScalarField& weights = *weights_;
160  weights.setOriented();
161 
162  // Set local references to mesh data
163  // Note that we should not use fvMesh sliced fields at this point yet
164  // since this causes a loop when generating weighting factors in
165  // coupledFvPatchField evaluation phase
166  const labelUList& owner = mesh_.owner();
167  const labelUList& neighbour = mesh_.neighbour();
168 
169  const vectorField& Cf = mesh_.faceCentres();
170  const vectorField& C = mesh_.cellCentres();
171  const vectorField& Sf = mesh_.faceAreas();
172 
173  // ... and reference to the internal field of the weighting factors
174  scalarField& w = weights.primitiveFieldRef();
175 
176  forAll(owner, facei)
177  {
178  // Note: mag in the dot-product.
179  // For all valid meshes, the non-orthogonality will be less than
180  // 90 deg and the dot-product will be positive. For invalid
181  // meshes (d & s <= 0), this will stabilise the calculation
182  // but the result will be poor.
183  scalar SfdOwn = mag(Sf[facei] & (Cf[facei] - C[owner[facei]]));
184  scalar SfdNei = mag(Sf[facei] & (C[neighbour[facei]] - Cf[facei]));
185  w[facei] = SfdNei/(SfdOwn + SfdNei);
186  }
187 
188  surfaceScalarField::Boundary& wBf = weights.boundaryFieldRef();
189 
190  forAll(mesh_.boundary(), patchi)
191  {
192  mesh_.boundary()[patchi].makeWeights(wBf[patchi]);
193  }
194 
195  if (debug)
196  {
197  Pout<< "surfaceInterpolation::makeWeights() : "
198  << "Finished constructing weighting factors for face interpolation"
199  << endl;
200  }
201 }
202 
203 
204 void Foam::surfaceInterpolation::makeDeltaCoeffs() const
205 {
206  if (debug)
207  {
208  Pout<< "surfaceInterpolation::makeDeltaCoeffs() : "
209  << "Constructing differencing factors array for face gradient"
210  << endl;
211  }
212 
213  // Force the construction of the weighting factors
214  // needed to make sure deltaCoeffs are calculated for parallel runs.
215  weights();
216 
217  deltaCoeffs_ = new surfaceScalarField
218  (
219  IOobject
220  (
221  "deltaCoeffs",
222  mesh_.pointsInstance(),
223  mesh_,
226  false // Do not register
227  ),
228  mesh_,
230  );
231  surfaceScalarField& deltaCoeffs = *deltaCoeffs_;
232  deltaCoeffs.setOriented();
233 
234 
235  // Set local references to mesh data
236  const volVectorField& C = mesh_.C();
237  const labelUList& owner = mesh_.owner();
238  const labelUList& neighbour = mesh_.neighbour();
239 
240  forAll(owner, facei)
241  {
242  deltaCoeffs[facei] = 1.0/mag(C[neighbour[facei]] - C[owner[facei]]);
243  }
244 
245  surfaceScalarField::Boundary& deltaCoeffsBf =
246  deltaCoeffs.boundaryFieldRef();
247 
248  forAll(deltaCoeffsBf, patchi)
249  {
250  deltaCoeffsBf[patchi] = 1.0/mag(mesh_.boundary()[patchi].delta());
251  }
252 }
253 
254 
255 void Foam::surfaceInterpolation::makeNonOrthDeltaCoeffs() const
256 {
257  if (debug)
258  {
259  Pout<< "surfaceInterpolation::makeNonOrthDeltaCoeffs() : "
260  << "Constructing differencing factors array for face gradient"
261  << endl;
262  }
263 
264  // Force the construction of the weighting factors
265  // needed to make sure deltaCoeffs are calculated for parallel runs.
266  weights();
267 
268  nonOrthDeltaCoeffs_ = new surfaceScalarField
269  (
270  IOobject
271  (
272  "nonOrthDeltaCoeffs",
273  mesh_.pointsInstance(),
274  mesh_,
277  false // Do not register
278  ),
279  mesh_,
281  );
282  surfaceScalarField& nonOrthDeltaCoeffs = *nonOrthDeltaCoeffs_;
283  nonOrthDeltaCoeffs.setOriented();
284 
285 
286  // Set local references to mesh data
287  const volVectorField& C = mesh_.C();
288  const labelUList& owner = mesh_.owner();
289  const labelUList& neighbour = mesh_.neighbour();
290  const surfaceVectorField& Sf = mesh_.Sf();
291  const surfaceScalarField& magSf = mesh_.magSf();
292 
293  forAll(owner, facei)
294  {
295  vector delta = C[neighbour[facei]] - C[owner[facei]];
296  vector unitArea = Sf[facei]/magSf[facei];
297 
298  // Standard cell-centre distance form
299  //NonOrthDeltaCoeffs[facei] = (unitArea & delta)/magSqr(delta);
300 
301  // Slightly under-relaxed form
302  //NonOrthDeltaCoeffs[facei] = 1.0/mag(delta);
303 
304  // More under-relaxed form
305  //NonOrthDeltaCoeffs[facei] = 1.0/(mag(unitArea & delta) + VSMALL);
306 
307  // Stabilised form for bad meshes
308  nonOrthDeltaCoeffs[facei] = 1.0/max(unitArea & delta, 0.05*mag(delta));
309  }
310 
311  surfaceScalarField::Boundary& nonOrthDeltaCoeffsBf =
312  nonOrthDeltaCoeffs.boundaryFieldRef();
313 
314  forAll(nonOrthDeltaCoeffsBf, patchi)
315  {
316  fvsPatchScalarField& patchDeltaCoeffs = nonOrthDeltaCoeffsBf[patchi];
317 
318  const fvPatch& p = patchDeltaCoeffs.patch();
319 
320  const vectorField patchDeltas(mesh_.boundary()[patchi].delta());
321 
322  forAll(p, patchFacei)
323  {
324  vector unitArea =
325  Sf.boundaryField()[patchi][patchFacei]
326  /magSf.boundaryField()[patchi][patchFacei];
327 
328  const vector& delta = patchDeltas[patchFacei];
329 
330  patchDeltaCoeffs[patchFacei] =
331  1.0/max(unitArea & delta, 0.05*mag(delta));
332  }
333  }
334 }
335 
336 
337 void Foam::surfaceInterpolation::makeNonOrthCorrectionVectors() const
338 {
339  if (debug)
340  {
341  Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : "
342  << "Constructing non-orthogonal correction vectors"
343  << endl;
344  }
345 
346  nonOrthCorrectionVectors_ = new surfaceVectorField
347  (
348  IOobject
349  (
350  "nonOrthCorrectionVectors",
351  mesh_.pointsInstance(),
352  mesh_,
355  false // Do not register
356  ),
357  mesh_,
358  dimless
359  );
360  surfaceVectorField& corrVecs = *nonOrthCorrectionVectors_;
361  corrVecs.setOriented();
362 
363  // Set local references to mesh data
364  const volVectorField& C = mesh_.C();
365  const labelUList& owner = mesh_.owner();
366  const labelUList& neighbour = mesh_.neighbour();
367  const surfaceVectorField& Sf = mesh_.Sf();
368  const surfaceScalarField& magSf = mesh_.magSf();
369  const surfaceScalarField& NonOrthDeltaCoeffs = nonOrthDeltaCoeffs();
370 
371  forAll(owner, facei)
372  {
373  vector unitArea = Sf[facei]/magSf[facei];
374  vector delta = C[neighbour[facei]] - C[owner[facei]];
375 
376  corrVecs[facei] = unitArea - delta*NonOrthDeltaCoeffs[facei];
377  }
378 
379  // Boundary correction vectors set to zero for boundary patches
380  // and calculated consistently with internal corrections for
381  // coupled patches
382 
383  surfaceVectorField::Boundary& corrVecsBf = corrVecs.boundaryFieldRef();
384 
385  forAll(corrVecsBf, patchi)
386  {
387  fvsPatchVectorField& patchCorrVecs = corrVecsBf[patchi];
388 
389  if (!patchCorrVecs.coupled())
390  {
391  patchCorrVecs = Zero;
392  }
393  else
394  {
395  const fvsPatchScalarField& patchNonOrthDeltaCoeffs =
396  NonOrthDeltaCoeffs.boundaryField()[patchi];
397 
398  const fvPatch& p = patchCorrVecs.patch();
399 
400  const vectorField patchDeltas(mesh_.boundary()[patchi].delta());
401 
402  forAll(p, patchFacei)
403  {
404  vector unitArea =
405  Sf.boundaryField()[patchi][patchFacei]
406  /magSf.boundaryField()[patchi][patchFacei];
407 
408  const vector& delta = patchDeltas[patchFacei];
409 
410  patchCorrVecs[patchFacei] =
411  unitArea - delta*patchNonOrthDeltaCoeffs[patchFacei];
412  }
413  }
414  }
415 
416  if (debug)
417  {
418  Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : "
419  << "Finished constructing non-orthogonal correction vectors"
420  << endl;
421  }
422 }
423 
424 
425 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::surfaceInterpolation::clearOut
void clearOut()
Clear all geometry and addressing.
Definition: surfaceInterpolation.C:48
volFields.H
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::dimless
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Dimensionless.
Definition: dimensionSets.H:50
Foam::dimLength
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:53
Foam::surfaceInterpolation::nonOrthDeltaCoeffs
const surfaceScalarField & nonOrthDeltaCoeffs() const
Return reference to non-orthogonal cell-centre difference.
Definition: surfaceInterpolation.C:102
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::fvsPatchScalarField
fvsPatchField< scalar > fvsPatchScalarField
Definition: fvsPatchFieldsFwd.H:45
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
surfaceFields.H
Foam::surfaceFields.
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
Foam::surfaceInterpolation::deltaCoeffs
const surfaceScalarField & deltaCoeffs() const
Return reference to cell-centre difference coefficients.
Definition: surfaceInterpolation.C:90
C
volScalarField & C
Definition: readThermalProperties.H:102
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
coupledFvPatch.H
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::deleteDemandDrivenData
void deleteDemandDrivenData(DataPtr &dataPtr)
Definition: demandDrivenData.H:42
Foam::fvsPatchVectorField
fvsPatchField< vector > fvsPatchVectorField
Definition: fvsPatchFieldsFwd.H:48
delta
scalar delta
Definition: LISASMDCalcMethod2.H:8
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::surfaceInterpolation::movePoints
bool movePoints()
Do what is necessary if the mesh has moved.
Definition: surfaceInterpolation.C:125
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:84
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::volVectorField
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:60
Foam::surfaceInterpolation::nonOrthCorrectionVectors
const surfaceVectorField & nonOrthCorrectionVectors() const
Return reference to non-orthogonality correction vectors.
Definition: surfaceInterpolation.C:114
Foam::surfaceScalarField
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
Definition: surfaceFieldsFwd.H:54
Foam::surfaceInterpolation::weights
const surfaceScalarField & weights() const
Return reference to linear difference weighting factors.
Definition: surfaceInterpolation.C:79
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::surfaceInterpolation::surfaceInterpolation
surfaceInterpolation(const fvMesh &)
Construct given an fvMesh.
Definition: surfaceInterpolation.C:59
Foam::surfaceInterpolation::~surfaceInterpolation
~surfaceInterpolation()
Destructor.
Definition: surfaceInterpolation.C:71
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:79
Foam::surfaceVectorField
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
Definition: surfaceFieldsFwd.H:57
Foam::GeometricField< scalar, fvsPatchField, surfaceMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:123
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)