age.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) 2018-2021 OpenFOAM Foundation
9  Copyright (C) 2021-2023 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 "age.H"
30 #include "fvmDiv.H"
31 #include "fvmLaplacian.H"
32 #include "fvOptions.H"
35 #include "turbulenceModel.H"
37 #include "wallFvPatch.H"
40 
41 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45 namespace functionObjects
46 {
47  defineTypeNameAndDebug(age, 0);
48  addToRunTimeSelectionTable(functionObject, age, dictionary);
49 }
50 }
51 
52 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
53 
54 Foam::wordList Foam::functionObjects::age::patchTypes() const
55 {
56  wordList result
57  (
58  mesh_.boundary().size(),
60  );
61 
62  forAll(mesh_.boundary(), patchi)
63  {
64  if (isA<wallFvPatch>(mesh_.boundary()[patchi]))
65  {
66  result[patchi] = fvPatchFieldBase::zeroGradientType();
67  }
68  }
69 
70  return result;
71 }
72 
73 
74 bool Foam::functionObjects::age::converged
75 (
76  const int nCorr,
77  const scalar initialResidual
78 ) const
79 {
80  if (initialResidual < tolerance_)
81  {
82  Info<< "Field " << typeName
83  << " converged in " << nCorr << " correctors"
84  << nl << endl;
85 
86  return true;
87  }
88 
89  return false;
90 }
91 
92 
93 template<class GeoField>
95 Foam::functionObjects::age::newField
96 (
97  const word& baseName,
98  const wordList patches
99 ) const
100 {
102  (
103  IOobject
104  (
105  scopedName(baseName),
106  time_.timeName(),
107  mesh_,
110  ),
111  mesh_,
113  patches
114  );
115 }
116 
117 
118 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
119 
121 (
122  const word& name,
123  const Time& runTime,
124  const dictionary& dict
125 )
126 :
128 {
129  read(dict);
130 }
131 
132 
133 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
134 
136 {
138  {
139  phiName_ = dict.getOrDefault<word>("phi", "phi");
140  rhoName_ = dict.getOrDefault<word>("rho", "rho");
141  schemesField_ = dict.getOrDefault<word>("schemesField", typeName);
142  tolerance_ = dict.getOrDefault<scalar>("tolerance", 1e-5);
143  nCorr_ = dict.getOrDefault<int>("nCorr", 5);
144  diffusion_ = dict.getOrDefault<bool>("diffusion", false);
145 
146  return true;
147  }
148 
149  return false;
150 }
151 
152 
154 {
155  auto tage = tmp<volScalarField>::New
156  (
157  IOobject
158  (
159  typeName,
160  mesh_.time().timeName(),
161  mesh_,
165  ),
166  mesh_,
168  patchTypes()
169  );
170  volScalarField& age = tage.ref();
171 
172  const word divScheme("div(phi," + schemesField_ + ")");
173 
174  // Set under-relaxation coeff
175  scalar relaxCoeff = 0;
176  mesh_.relaxEquation(schemesField_, relaxCoeff);
177 
179 
180 
181  // This only works because the null constructed inletValue for an
182  // inletOutletFvPatchField is zero. If we needed any other value we would
183  // have to loop over the inletOutlet patches and explicitly set the
184  // inletValues. We would need to change the interface of inletOutlet in
185  // order to do this.
186 
187  const auto& phi = mesh_.lookupObject<surfaceScalarField>(phiName_);
188 
189  if (phi.dimensions() == dimMass/dimTime)
190  {
191  const auto& rho = mesh_.lookupObject<volScalarField>(rhoName_);
192 
193  tmp<volScalarField> tmuEff;
194  word laplacianScheme;
195 
196  if (diffusion_)
197  {
198  tmuEff =
199  mesh_.lookupObject<compressible::turbulenceModel>
200  (
202  ).muEff();
203 
204  laplacianScheme =
205  "laplacian(" + tmuEff().name() + ',' + schemesField_ + ")";
206  }
207 
208  for (int i = 0; i <= nCorr_; ++i)
209  {
210  fvScalarMatrix ageEqn
211  (
212  fvm::div(phi, age, divScheme) == rho //+ fvOptions(rho, age)
213  );
214 
215  if (diffusion_)
216  {
217  ageEqn -= fvm::laplacian(tmuEff(), age, laplacianScheme);
218  }
219 
220  ageEqn.relax(relaxCoeff);
221 
222  fvOptions.constrain(ageEqn);
223 
224  if (converged(i, ageEqn.solve().initialResidual()))
225  {
226  break;
227  };
228 
229  fvOptions.correct(age);
230  }
231  }
232  else
233  {
234  tmp<volScalarField> tnuEff;
235  word laplacianScheme;
236 
237  if (diffusion_)
238  {
239  tnuEff =
240  mesh_.lookupObject<incompressible::turbulenceModel>
241  (
243  ).nuEff();
244 
245  laplacianScheme =
246  "laplacian(" + tnuEff().name() + ',' + schemesField_ + ")";
247  }
248 
249  for (int i = 0; i <= nCorr_; ++i)
250  {
251  fvScalarMatrix ageEqn
252  (
253  fvm::div(phi, age, divScheme)
254  == dimensionedScalar(1) + fvOptions(age)
255  );
256 
257  if (diffusion_)
258  {
259  ageEqn -= fvm::laplacian(tnuEff(), age, laplacianScheme);
260  }
261 
262  ageEqn.relax(relaxCoeff);
263 
264  fvOptions.constrain(ageEqn);
265 
266  if (converged(i, ageEqn.solve().initialResidual()))
267  {
268  break;
269  }
270 
271  fvOptions.correct(age);
272  }
273  }
274 
275  Info<< "Min/max age:"
276  << min(age).value() << ' '
277  << max(age).value()
278  << endl;
279 
280  // Workaround
281  word fieldName = typeName;
282 
283  return store(fieldName, tage);
284 }
285 
286 
288 {
289  return writeObject(typeName);
290 }
291 
292 
293 // ************************************************************************* //
static const word & zeroGradientType() noexcept
The type name for zeroGradient patch fields.
Definition: fvPatchField.H:221
virtual bool execute()
Execute.
Definition: age.C:146
virtual bool read(const dictionary &)
Read the data.
Definition: age.C:128
dictionary dict
defineTypeNameAndDebug(ObukhovLength, 0)
fvMatrix< scalar > fvScalarMatrix
Definition: fvMatricesFwd.H:37
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
age(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
Definition: age.C:114
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
wordList patchTypes(nPatches)
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
Calculate the matrix for the laplacian of the field.
Generic dimensioned Type class.
IncompressibleTurbulenceModel< transportModel > turbulenceModel
Ignore writing from objectRegistry::writeObject()
Templated wrapper class to provide compressible turbulence models thermal diffusivity based thermal t...
Finite-volume options.
Definition: fvOptions.H:51
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
Macros for easy insertion into run-time selection tables.
fv::options & fvOptions
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:127
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
static const char *const typeName
Typename for Field.
Definition: Field.H:86
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
static const word propertiesName
Default name of the turbulence properties dictionary.
A class for handling words, derived from Foam::string.
Definition: word.H:63
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
Reading is optional [identical to LAZY_READ].
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition: tmp.H:206
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
tmp< fvMatrix< Type > > div(const surfaceScalarField &flux, const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvmDiv.C:41
addToRunTimeSelectionTable(functionObject, ObukhovLength, dictionary)
Calculate the matrix for the divergence of the given field and flux.
List< word > wordList
List of word.
Definition: fileName.H:59
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
tmp< fvMatrix< Type > > laplacian(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvmLaplacian.C:41
const polyBoundaryMesh & patches
Nothing to be read.
Automatically write from objectRegistry::writeObject()
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:51
messageStream Info
Information stream (stdout output on master, null elsewhere)
Internal & ref(const bool updateAccessTime=true)
Same as internalFieldRef()
const fvBoundaryMesh & boundary() const noexcept
Return reference to boundary mesh.
Definition: fvMesh.H:395
virtual bool read(const dictionary &dict)
Read optional controls.
virtual bool write()
Write.
Definition: age.C:280
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:49
A class for managing temporary objects.
Definition: HashPtrTable.H:50
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition: autoPtr.H:178
static options & New(const fvMesh &mesh)
Construct fvOptions and register to database if not present.
Definition: fvOptions.C:96
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
const fvMesh & mesh_
Reference to the fvMesh.
Do not request registration (bool: false)
Namespace for OpenFOAM.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127