basicFvGeometryScheme.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) 2020-2021 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "basicFvGeometryScheme.H"
30 #include "surfaceFields.H"
31 #include "volFields.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  defineTypeNameAndDebug(basicFvGeometryScheme, 0);
38  addToRunTimeSelectionTable(fvGeometryScheme, basicFvGeometryScheme, dict);
39 }
40 
41 
42 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
43 
44 Foam::basicFvGeometryScheme::basicFvGeometryScheme
45 (
46  const fvMesh& mesh,
47  const dictionary& dict
48 )
49 :
51 {}
52 
53 
54 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
55 
57 {
58  if (debug)
59  {
60  Pout<< "basicFvGeometryScheme::movePoints() : "
61  << "recalculating primitiveMesh centres" << endl;
62  }
63  // Use lower level to calculate the geometry
64  const_cast<fvMesh&>(mesh_).primitiveMesh::updateGeom();
65 }
66 
67 
69 {
70  if (debug)
71  {
72  Pout<< "basicFvGeometryScheme::weights() : "
73  << "Constructing weighting factors for face interpolation"
74  << endl;
75  }
76 
78  (
80  (
81  IOobject
82  (
83  "weights",
84  mesh_.pointsInstance(),
85  mesh_,
88  false // Do not register
89  ),
90  mesh_,
91  dimless
92  )
93  );
94  surfaceScalarField& weights = tweights.ref();
95  weights.setOriented();
96 
97  // Set local references to mesh data
98  // Note that we should not use fvMesh sliced fields at this point yet
99  // since this causes a loop when generating weighting factors in
100  // coupledFvPatchField evaluation phase
101  const labelUList& owner = mesh_.owner();
102  const labelUList& neighbour = mesh_.neighbour();
103 
104  const vectorField& Cf = mesh_.faceCentres();
105  const vectorField& C = mesh_.cellCentres();
106  const vectorField& Sf = mesh_.faceAreas();
107 
108  // ... and reference to the internal field of the weighting factors
109  scalarField& w = weights.primitiveFieldRef();
110 
111  forAll(owner, facei)
112  {
113  // Note: mag in the dot-product.
114  // For all valid meshes, the non-orthogonality will be less than
115  // 90 deg and the dot-product will be positive. For invalid
116  // meshes (d & s <= 0), this will stabilise the calculation
117  // but the result will be poor.
118  scalar SfdOwn = mag(Sf[facei] & (Cf[facei] - C[owner[facei]]));
119  scalar SfdNei = mag(Sf[facei] & (C[neighbour[facei]] - Cf[facei]));
120 
121  if (mag(SfdOwn + SfdNei) > ROOTVSMALL)
122  {
123  w[facei] = SfdNei/(SfdOwn + SfdNei);
124  }
125  else
126  {
127  w[facei] = 0.5;
128  }
129  }
130 
131  surfaceScalarField::Boundary& wBf = weights.boundaryFieldRef();
132 
133  forAll(mesh_.boundary(), patchi)
134  {
135  mesh_.boundary()[patchi].makeWeights(wBf[patchi]);
136  }
137 
138  if (debug)
139  {
140  Pout<< "basicFvGeometryScheme::weights : "
141  << "Finished constructing weighting factors for face interpolation"
142  << endl;
143  }
144  return tweights;
145 }
146 
147 
150 {
151  if (debug)
152  {
153  Pout<< "basicFvGeometryScheme::deltaCoeffs() : "
154  << "Constructing differencing factors array for face gradient"
155  << endl;
156  }
157 
158  // Force the construction of the weighting factors
159  // needed to make sure deltaCoeffs are calculated for parallel runs.
160  (void)mesh_.weights();
161 
162  tmp<surfaceScalarField> tdeltaCoeffs
163  (
165  (
166  IOobject
167  (
168  "deltaCoeffs",
169  mesh_.pointsInstance(),
170  mesh_,
173  false // Do not register
174  ),
175  mesh_,
177  )
178  );
179  surfaceScalarField& deltaCoeffs = tdeltaCoeffs.ref();
180  deltaCoeffs.setOriented();
181 
182 
183  // Set local references to mesh data
184  const volVectorField& C = mesh_.C();
185  const labelUList& owner = mesh_.owner();
186  const labelUList& neighbour = mesh_.neighbour();
187 
188  forAll(owner, facei)
189  {
190  deltaCoeffs[facei] = 1.0/mag(C[neighbour[facei]] - C[owner[facei]]);
191  }
192 
193  surfaceScalarField::Boundary& deltaCoeffsBf =
194  deltaCoeffs.boundaryFieldRef();
195 
196  forAll(deltaCoeffsBf, patchi)
197  {
198  const fvPatch& p = mesh_.boundary()[patchi];
199  deltaCoeffsBf[patchi] = 1.0/mag(p.delta());
200 
201  // Optionally correct
202  p.makeDeltaCoeffs(deltaCoeffsBf[patchi]);
203  }
204 
205  return tdeltaCoeffs;
206 }
207 
208 
211 {
212  if (debug)
213  {
214  Pout<< "basicFvGeometryScheme::nonOrthDeltaCoeffs() : "
215  << "Constructing differencing factors array for face gradient"
216  << endl;
217  }
218 
219  // Force the construction of the weighting factors
220  // needed to make sure deltaCoeffs are calculated for parallel runs.
221  weights();
222 
223  tmp<surfaceScalarField> tnonOrthDeltaCoeffs
224  (
226  (
227  IOobject
228  (
229  "nonOrthDeltaCoeffs",
230  mesh_.pointsInstance(),
231  mesh_,
234  false // Do not register
235  ),
236  mesh_,
238  )
239  );
240  surfaceScalarField& nonOrthDeltaCoeffs = tnonOrthDeltaCoeffs.ref();
241  nonOrthDeltaCoeffs.setOriented();
242 
243 
244  // Set local references to mesh data
245  const volVectorField& C = mesh_.C();
246  const labelUList& owner = mesh_.owner();
247  const labelUList& neighbour = mesh_.neighbour();
248  const surfaceVectorField& Sf = mesh_.Sf();
249  const surfaceScalarField& magSf = mesh_.magSf();
250 
251  forAll(owner, facei)
252  {
253  vector delta = C[neighbour[facei]] - C[owner[facei]];
254  vector unitArea = Sf[facei]/magSf[facei];
255 
256  // Standard cell-centre distance form
257  //NonOrthDeltaCoeffs[facei] = (unitArea & delta)/magSqr(delta);
258 
259  // Slightly under-relaxed form
260  //NonOrthDeltaCoeffs[facei] = 1.0/mag(delta);
261 
262  // More under-relaxed form
263  //NonOrthDeltaCoeffs[facei] = 1.0/(mag(unitArea & delta) + VSMALL);
264 
265  // Stabilised form for bad meshes
266  nonOrthDeltaCoeffs[facei] = 1.0/max(unitArea & delta, 0.05*mag(delta));
267  }
268 
269  surfaceScalarField::Boundary& nonOrthDeltaCoeffsBf =
270  nonOrthDeltaCoeffs.boundaryFieldRef();
271 
272  forAll(nonOrthDeltaCoeffsBf, patchi)
273  {
274  fvsPatchScalarField& patchDeltaCoeffs = nonOrthDeltaCoeffsBf[patchi];
275 
276  const fvPatch& p = patchDeltaCoeffs.patch();
277 
278  const vectorField patchDeltas(mesh_.boundary()[patchi].delta());
279 
280  forAll(p, patchFacei)
281  {
282  vector unitArea =
283  Sf.boundaryField()[patchi][patchFacei]
284  /magSf.boundaryField()[patchi][patchFacei];
285 
286  const vector& delta = patchDeltas[patchFacei];
287 
288  patchDeltaCoeffs[patchFacei] =
289  1.0/max(unitArea & delta, 0.05*mag(delta));
290  }
291 
292  // Optionally correct
293  p.makeNonOrthoDeltaCoeffs(patchDeltaCoeffs);
294  }
295  return tnonOrthDeltaCoeffs;
296 }
297 
298 
301 {
302  if (debug)
303  {
304  Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : "
305  << "Constructing non-orthogonal correction vectors"
306  << endl;
307  }
308 
309  tmp<surfaceVectorField> tnonOrthCorrectionVectors
310  (
312  (
313  IOobject
314  (
315  "nonOrthCorrectionVectors",
316  mesh_.pointsInstance(),
317  mesh_,
320  false // Do not register
321  ),
322  mesh_,
323  dimless
324  )
325  );
326  surfaceVectorField& corrVecs = tnonOrthCorrectionVectors.ref();
327  corrVecs.setOriented();
328 
329  // Set local references to mesh data
330  const volVectorField& C = mesh_.C();
331  const labelUList& owner = mesh_.owner();
332  const labelUList& neighbour = mesh_.neighbour();
333  const surfaceVectorField& Sf = mesh_.Sf();
334  const surfaceScalarField& magSf = mesh_.magSf();
335  tmp<surfaceScalarField> tNonOrthDeltaCoeffs(nonOrthDeltaCoeffs());
336  const surfaceScalarField& NonOrthDeltaCoeffs = tNonOrthDeltaCoeffs();
337 
338  forAll(owner, facei)
339  {
340  vector unitArea = Sf[facei]/magSf[facei];
341  vector delta = C[neighbour[facei]] - C[owner[facei]];
342 
343  corrVecs[facei] = unitArea - delta*NonOrthDeltaCoeffs[facei];
344  }
345 
346  // Boundary correction vectors set to zero for boundary patches
347  // and calculated consistently with internal corrections for
348  // coupled patches
349 
350  surfaceVectorField::Boundary& corrVecsBf = corrVecs.boundaryFieldRef();
351 
352  forAll(corrVecsBf, patchi)
353  {
354  fvsPatchVectorField& patchCorrVecs = corrVecsBf[patchi];
355 
356  const fvPatch& p = patchCorrVecs.patch();
357 
358  if (!patchCorrVecs.coupled())
359  {
360  patchCorrVecs = Zero;
361  }
362  else
363  {
364  const fvsPatchScalarField& patchNonOrthDeltaCoeffs =
365  NonOrthDeltaCoeffs.boundaryField()[patchi];
366 
367  const vectorField patchDeltas(mesh_.boundary()[patchi].delta());
368 
369  forAll(p, patchFacei)
370  {
371  vector unitArea =
372  Sf.boundaryField()[patchi][patchFacei]
373  /magSf.boundaryField()[patchi][patchFacei];
374 
375  const vector& delta = patchDeltas[patchFacei];
376 
377  patchCorrVecs[patchFacei] =
378  unitArea - delta*patchNonOrthDeltaCoeffs[patchFacei];
379  }
380  }
381 
382  // Optionally correct
383  p.makeNonOrthoCorrVectors(patchCorrVecs);
384  }
385 
386  if (debug)
387  {
388  Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : "
389  << "Finished constructing non-orthogonal correction vectors"
390  << endl;
391  }
392  return tnonOrthCorrectionVectors;
393 }
394 
395 
396 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
volFields.H
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::dimLength
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:52
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::fvsPatchField
An abstract base class with a fat-interface to all derived classes covering all possible ways in whic...
Definition: fvsPatchField.H:68
Foam::basicFvGeometryScheme::deltaCoeffs
virtual tmp< surfaceScalarField > deltaCoeffs() const
Return cell-centre difference coefficients.
Definition: basicFvGeometryScheme.C:149
Foam::basicFvGeometryScheme::weights
virtual tmp< surfaceScalarField > weights() const
Return linear difference weighting factors.
Definition: basicFvGeometryScheme.C:68
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
surfaceFields.H
Foam::surfaceFields.
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::fvGeometryScheme
Abstract base class for geometry calculation schemes.
Definition: fvGeometryScheme.H:56
Foam::Field< vector >
Foam::basicFvGeometryScheme::nonOrthDeltaCoeffs
virtual tmp< surfaceScalarField > nonOrthDeltaCoeffs() const
Return non-orthogonal cell-centre difference coefficients.
Definition: basicFvGeometryScheme.C:210
Foam::fvPatch
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:65
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
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::C::C
C()
Construct null.
Definition: C.C:43
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::basicFvGeometryScheme::nonOrthCorrectionVectors
virtual tmp< surfaceVectorField > nonOrthCorrectionVectors() const
Return non-orthogonality correction vectors.
Definition: basicFvGeometryScheme.C:300
Foam::basicFvGeometryScheme::movePoints
virtual void movePoints()
Do what is necessary if the mesh has moved.
Definition: basicFvGeometryScheme.C:56
Foam::fvsPatchField::patch
const fvPatch & patch() const
Return patch.
Definition: fvsPatchField.H:281
Foam::GeometricField::ref
Internal & ref(const bool updateAccessTime=true)
Return a reference to the dimensioned internal field.
Definition: GeometricField.C:749
Foam::Vector< scalar >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::UList< label >
Foam::C
Graphite solid properties.
Definition: C.H:50
Foam::primitiveMesh::updateGeom
virtual void updateGeom()
Update all geometric data.
Definition: primitiveMesh.C:365
Foam::GeometricField< scalar, fvsPatchField, surfaceMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:188
basicFvGeometryScheme.H
Foam::fvsPatchField::coupled
virtual bool coupled() const
Return true if this patch field is coupled.
Definition: fvsPatchField.H:310
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::fvGeometryScheme::mesh_
const fvMesh & mesh_
Hold reference to mesh.
Definition: fvGeometryScheme.H:72
Foam::GeometricField::boundaryField
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Definition: GeometricFieldI.H:62
Foam::dimless
const dimensionSet dimless
Dimensionless.
Definition: dimensionSets.C:189