fvMeshGeometry.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-2017,2022 OpenFOAM Foundation
9  Copyright (C) 2020-2022 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 \*---------------------------------------------------------------------------*/
28 
29 #include "fvMesh.H"
30 #include "Time.H"
31 #include "volFields.H"
32 #include "surfaceFields.H"
33 #include "slicedVolFields.H"
35 #include "SubField.H"
36 #include "cyclicFvPatchFields.H"
37 #include "cyclicAMIFvPatchFields.H"
38 
39 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
40 
41 void Foam::fvMesh::makeSf() const
42 {
43  DebugInFunction << "Assembling face areas" << endl;
44 
45  // It is an error to attempt to recalculate
46  // if the pointer is already set
47  if (SfPtr_)
48  {
50  << "face areas already exist"
51  << abort(FatalError);
52  }
53 
55  (
56  IOobject
57  (
58  "S",
60  meshSubDir,
61  *this,
65  ),
66  *this,
67  dimArea,
69  );
70 
72 }
73 
74 
75 void Foam::fvMesh::makeMagSf() const
76 {
77  DebugInFunction << "Assembling mag face areas" << endl;
78 
79  // It is an error to attempt to recalculate
80  // if the pointer is already set
81  if (magSfPtr_)
82  {
84  << "mag face areas already exist"
85  << abort(FatalError);
86  }
87 
88  // Note: Added stabilisation for faces with exactly zero area.
89  // These should be caught on mesh checking but at least this stops
90  // the code from producing Nans.
91  magSfPtr_ = new surfaceScalarField
92  (
93  IOobject
94  (
95  "magSf",
96  pointsInstance(),
97  meshSubDir,
98  *this,
102  ),
103  mag(Sf()) + dimensionedScalar("vs", dimArea, VSMALL)
104  );
105 }
106 
107 
108 void Foam::fvMesh::makeC() const
109 {
110  DebugInFunction << "Assembling cell centres" << endl;
111 
112  // It is an error to attempt to recalculate
113  // if the pointer is already set
114  if (CPtr_)
115  {
117  << "cell centres already exist"
118  << abort(FatalError);
119  }
120 
121  // Construct as slices. Only preserve processor (not e.g. cyclic)
122 
123  CPtr_ = new slicedVolVectorField
124  (
125  IOobject
126  (
127  "C",
128  pointsInstance(),
129  meshSubDir,
130  *this,
134  ),
135  *this,
136  dimLength,
137  cellCentres(),
138  faceCentres(),
139  true, //preserveCouples
140  true //preserveProcOnly
141  );
142 }
143 
144 
145 void Foam::fvMesh::makeCf() const
146 {
147  DebugInFunction << "Assembling face centres" << endl;
148 
149  // It is an error to attempt to recalculate
150  // if the pointer is already set
151  if (CfPtr_)
152  {
154  << "face centres already exist"
155  << abort(FatalError);
156  }
157 
158  CfPtr_ = new slicedSurfaceVectorField
159  (
160  IOobject
161  (
162  "Cf",
163  pointsInstance(),
164  meshSubDir,
165  *this,
169  ),
170  *this,
171  dimLength,
172  faceCentres()
173  );
174 }
175 
176 
177 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
178 
180 {
181  if (!VPtr_)
182  {
184  << "Constructing from primitiveMesh::cellVolumes()" << endl;
185 
187  (
188  IOobject
189  (
190  "V",
191  time().timeName(),
192  *this,
196  ),
197  *this,
198  dimVolume,
199  cellVolumes()
200  );
201  }
202 
203  return *VPtr_;
204 }
205 
206 
208 {
209  if (!V0Ptr_)
210  {
212  << "V0 is not available"
214  }
215 
216  return *V0Ptr_;
217 }
218 
219 
221 {
222  if (!V0Ptr_)
223  {
225  << "V0 is not available"
227  }
228 
229  return *V0Ptr_;
230 }
231 
232 
234 {
235  if (!V00Ptr_)
236  {
237  DebugInFunction << "Constructing from V0" << endl;
238 
239  V00Ptr_ = new DimensionedField<scalar, volMesh>
240  (
241  IOobject
242  (
243  "V00",
244  time().timeName(),
245  *this,
249  ),
250  V0()
251  );
252 
253 
254  // If V00 is used then V0 should be stored for restart
255  V0Ptr_->writeOpt(IOobject::AUTO_WRITE);
256  }
257 
258  return *V00Ptr_;
259 }
260 
261 
263 {
264  if (!steady() && moving() && time().subCycling())
265  {
266  const TimeState& ts = time();
267  const TimeState& ts0 = time().prevTimeState();
268 
269  scalar tFrac =
270  (
271  ts.value() - (ts0.value() - ts0.deltaTValue())
272  )/ts0.deltaTValue();
273 
274  if (tFrac < (1 - SMALL))
275  {
276  return V0() + tFrac*(V() - V0());
277  }
278  }
279 
280  return V();
281 }
282 
283 
285 {
286  if (!steady() && moving() && time().subCycling())
287  {
288  const TimeState& ts = time();
289  const TimeState& ts0 = time().prevTimeState();
290 
291  scalar t0Frac =
292  (
293  (ts.value() - ts.deltaTValue())
294  - (ts0.value() - ts0.deltaTValue())
295  )/ts0.deltaTValue();
296 
297  if (t0Frac > SMALL)
298  {
299  return V0() + t0Frac*(V() - V0());
300  }
301  }
302 
303  return V0();
304 }
305 
306 
308 {
309  if (!SfPtr_)
310  {
311  makeSf();
312  }
313 
314  return *SfPtr_;
315 }
316 
317 
319 {
320  if (!magSfPtr_)
321  {
322  makeMagSf();
323  }
324 
325  return *magSfPtr_;
326 }
327 
328 
330 {
331  auto tunitVectors = tmp<surfaceVectorField>::New
332  (
333  IOobject
334  (
335  "unit(Sf)",
336  pointsInstance(),
337  meshSubDir,
338  *this,
342  ),
343  *this,
344  dimless,
345  (this->Sf() / this->magSf())
346  );
347 
348  tunitVectors.ref().oriented() = this->Sf().oriented();
349  return tunitVectors;
350 }
351 
352 
354 {
355  if (!CPtr_)
356  {
357  makeC();
358  }
359 
360  return *CPtr_;
361 }
362 
363 
365 {
366  if (!CfPtr_)
367  {
368  makeCf();
369  }
370 
371  return *CfPtr_;
372 }
373 
374 
376 {
377  DebugInFunction << "Calculating face deltas" << endl;
378 
379  tmp<surfaceVectorField> tdelta
380  (
382  (
383  IOobject
384  (
385  "delta",
386  pointsInstance(),
387  meshSubDir,
388  *this,
392  ),
393  *this,
394  dimLength
395  )
396  );
397  surfaceVectorField& delta = tdelta.ref();
398  delta.setOriented();
399 
400  const volVectorField& C = this->C();
401  const labelUList& owner = this->owner();
402  const labelUList& neighbour = this->neighbour();
403 
404  forAll(owner, facei)
405  {
406  delta[facei] = C[neighbour[facei]] - C[owner[facei]];
407  }
408 
409  surfaceVectorField::Boundary& deltabf = delta.boundaryFieldRef();
410 
411  forAll(deltabf, patchi)
412  {
413  deltabf[patchi] = boundary()[patchi].delta();
414  }
415 
416  return tdelta;
417 }
418 
419 
421 {
422  if (!phiPtr_)
423  {
425  << "mesh flux field does not exist, is the mesh actually moving?"
426  << abort(FatalError);
427  }
428 
429  // Set zero current time
430  // mesh motion fluxes if the time has been incremented
431  if (!time().subCycling() && phiPtr_->timeIndex() != time().timeIndex())
432  {
433  (*phiPtr_) = dimensionedScalar(dimVolume/dimTime, Zero);
434  }
436  phiPtr_->setOriented();
437 
438  return *phiPtr_;
439 }
440 
441 
443 {
444  if (!phiPtr_)
445  {
446  return nullptr;
447  }
448  else
449  {
450  // Return non-const reference
451  refPtr<surfaceScalarField> p;
452  p.ref(*phiPtr_);
453  return p;
454  }
455 }
456 
457 
458 // ************************************************************************* //
Foam::surfaceFields.
faceListList boundary
scalar delta
const surfaceVectorField & Sf() const
Return cell face area vectors.
void makeC() const
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Specialisation of DimensionedField that holds a slice of a given field so that it acts as a Dimension...
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
const surfaceVectorField & Cf() const
Return face centres as surfaceVectorField.
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:410
const surfaceScalarField & phi() const
Return cell face motion fluxes.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
const DimensionedField< scalar, volMesh > & V00() const
Return old-old-time cell volumes.
GeometricBoundaryField< vector, fvsPatchField, surfaceMesh > Boundary
Type of boundary fields.
void makeCf() const
Ignore writing from objectRegistry::writeObject()
const dimensionSet dimless
Dimensionless.
DimensionedField< scalar, volMesh > & setV0()
Return old-time cell volumes.
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:82
A class for managing references or pointers (no reference counting)
Definition: HashPtrTable.H:49
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
word timeName
Definition: getTimeIndex.H:3
const dimensionSet dimVolume(pow3(dimLength))
Definition: dimensionSets.H:58
tmp< DimensionedField< scalar, volMesh > > Vsc() const
Return sub-cycle cell volumes.
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:853
const DimensionedField< scalar, volMesh > & V0() const
Return old-time cell volumes.
SlicedGeometricField< vector, fvsPatchField, slicedFvsPatchField, surfaceMesh > slicedSurfaceVectorField
#define DebugInFunction
Report an information message using Foam::Info.
void setOriented(bool on=true) noexcept
Set the oriented flag: on/off.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition: tmp.H:206
refPtr< surfaceScalarField > setPhi()
Return cell face motion fluxes (or null)
SlicedGeometricField< vector, fvPatchField, slicedFvPatchField, volMesh > slicedVolVectorField
errorManip< error > abort(error &err)
Definition: errorManip.H:139
tmp< DimensionedField< scalar, volMesh > > Vsc0() const
Return sub-cycle old-time cell volumes.
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
void makeMagSf() const
tmp< surfaceVectorField > delta() const
Return face deltas as surfaceVectorField.
volScalarField & C
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:50
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
const vectorField & faceAreas() const
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: areaFieldsFwd.H:42
Nothing to be read.
Automatically write from objectRegistry::writeObject()
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:51
slicedSurfaceVectorField * SfPtr_
Face area vectors.
Definition: fvMesh.H:127
Internal & ref(const bool updateAccessTime=true)
Same as internalFieldRef()
const volVectorField & C() const
Return cell centres as volVectorField.
volScalarField & p
A class for managing temporary objects.
Definition: HashPtrTable.H:50
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
Request registration (bool: true)
tmp< surfaceVectorField > unitSf() const
Return cell face unit normals.
void makeSf() const
Do not request registration (bool: false)
const dimensionSet dimArea(sqr(dimLength))
Definition: dimensionSets.H:57
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127