age.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2018-2025 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 "age.H"
27 #include "fvmDiv.H"
28 #include "fvmLaplacian.H"
29 #include "fvModels.H"
30 #include "fvConstraints.H"
31 #include "momentumTransportModel.H"
33 #include "wallFvPatch.H"
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41 namespace functionObjects
42 {
45 }
46 }
47 
48 
49 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
50 
51 Foam::wordList Foam::functionObjects::age::patchTypes() const
52 {
53  wordList result
54  (
55  mesh_.boundary().size(),
57  );
58 
60  {
61  if (isA<wallFvPatch>(mesh_.boundary()[patchi]))
62  {
64  }
65  }
66 
67  return result;
68 }
69 
70 
71 bool Foam::functionObjects::age::converged
72 (
73  const int nCorr,
74  const scalar initialResidual
75 ) const
76 {
77  if (initialResidual < tolerance_)
78  {
79  Info<< "Field " << typeName
80  << " converged in " << nCorr << " correctors\n" << endl;
81 
82  return true;
83  }
84  else
85  {
86  return false;
87  }
88 }
89 
90 
91 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
92 
94 (
95  const word& name,
96  const Time& runTime,
97  const dictionary& dict
98 )
99 :
100  fvMeshFunctionObject(name, runTime, dict)
101 {
102  read(dict);
103 }
104 
105 
106 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
107 
109 {}
110 
111 
112 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
113 
115 {
116  phiName_ = dict.lookupOrDefault<word>("phi", "phi");
117  rhoName_ = dict.lookupOrDefault<word>("rho", "rho");
118  nCorr_ = dict.lookupOrDefaultBackwardsCompatible<int>
119  (
120  {"nCorrectors", "nCorr"},
121  5
122  );
123  schemesField_ = dict.lookupOrDefault<word>("schemesField", typeName);
124  diffusion_ = dict.lookupOrDefault<Switch>("diffusion", false);
125  tolerance_ = dict.lookupOrDefault<scalar>("tolerance", 1e-5);
126 
127  return true;
128 }
129 
130 
132 {
133  return wordList{phiName_, rhoName_};
134 }
135 
136 
138 {
140  (
141  new volScalarField
142  (
143  IOobject
144  (
145  typeName,
146  time_.name(),
147  mesh_,
150  false
151  ),
152  mesh_,
154  patchTypes()
155  )
156  );
157  volScalarField& age = tage.ref();
158 
159  const word divScheme("div(phi," + schemesField_ + ")");
160 
161  // Set under-relaxation coeff
162  scalar relaxCoeff = 0.0;
163  if (mesh_.solution().relaxEquation(schemesField_))
164  {
165  relaxCoeff = mesh_.solution().equationRelaxationFactor(schemesField_);
166  }
167 
170  (
172  );
173 
174  const surfaceScalarField& phi =
175  mesh_.lookupObject<surfaceScalarField>(phiName_);
176 
177  if (phi.dimensions() == dimMass/dimTime)
178  {
179  const volScalarField& rho =
180  mesh_.lookupObject<volScalarField>(rhoName_);
181 
182  const word laplacianScheme("laplacian(muEff," + schemesField_ + ")");
183 
184  tmp<volScalarField> tnuEff;
185  if (diffusion_)
186  {
187  tnuEff = mesh_.lookupType<momentumTransportModel>().nuEff();
188  }
189 
190  for (int i=0; i<=nCorr_; i++)
191  {
192  fvScalarMatrix ageEqn
193  (
194  fvm::div(phi, age, divScheme) == rho + fvModels.source(rho, age)
195  );
196 
197  if (diffusion_)
198  {
199  ageEqn -= fvm::laplacian(rho*tnuEff(), age, laplacianScheme);
200  }
201 
202  ageEqn.relax(relaxCoeff);
203 
204  fvConstraints.constrain(ageEqn);
205 
206  if (converged(i, ageEqn.solve(schemesField_).initialResidual()))
207  {
208  break;
209  };
210 
212  }
213  }
214  else
215  {
216  tmp<volScalarField> tnuEff;
217  word laplacianScheme;
218 
219  if (diffusion_)
220  {
221  tnuEff = mesh_.lookupType<momentumTransportModel>().nuEff();
222 
223  laplacianScheme =
224  "laplacian(" + tnuEff().name() + ',' + schemesField_ + ")";
225  }
226 
227  for (int i=0; i<=nCorr_; i++)
228  {
229  fvScalarMatrix ageEqn
230  (
231  fvm::div(phi, age, divScheme)
233  );
234 
235  if (diffusion_)
236  {
237  ageEqn -= fvm::laplacian(tnuEff(), age, laplacianScheme);
238  }
239 
240  ageEqn.relax(relaxCoeff);
241 
242  fvConstraints.constrain(ageEqn);
243 
244  if (converged(i, ageEqn.solve(schemesField_).initialResidual()))
245  {
246  break;
247  }
248 
250  }
251  }
252 
253  Info<< "Min/max age:" << min(age).value()
254  << ' ' << max(age).value() << endl;
255 
256  store(tage);
257 
258  return true;
259 }
260 
261 
263 {
264  return writeObject(typeName);
265 }
266 
267 
268 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
Macros for easy insertion into run-time selection tables.
const dimensionSet & dimensions() const
Return dimensions.
static const char *const typeName
Definition: Field.H:106
Generic GeometricField class.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:61
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
static autoPtr< dictionary > New(Istream &)
Construct top-level dictionary on freestore from Istream.
Definition: dictionaryIO.C:103
Abstract base-class for Time/database functionObjects.
Calculates and writes out the time taken for a particle to travel from an inlet to the location....
Definition: age.H:132
age(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
Definition: age.C:94
virtual wordList fields() const
Return the list of fields required.
Definition: age.C:131
virtual ~age()
Destructor.
Definition: age.C:108
virtual bool execute()
Execute.
Definition: age.C:137
virtual bool write()
Write.
Definition: age.C:262
virtual bool read(const dictionary &)
Read the data.
Definition: age.C:114
Specialisation of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
const fvMesh & mesh_
Reference to the fvMesh.
Finite volume constraints.
Definition: fvConstraints.H:67
bool constrain(fvMatrix< Type > &eqn) const
Apply constraints to an equation.
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition: fvMatrix.H:118
void relax(const scalar alpha)
Relax matrix (for steady-state solution).
Definition: fvMatrix.C:603
SolverPerformance< Type > solve(const dictionary &)
Solve segregated or coupled returning the solution statistics.
Definition: fvMatrixSolve.C:58
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:962
Finite volume models.
Definition: fvModels.H:65
tmp< fvMatrix< Type > > source(const VolField< Type > &field) const
Return source for an equation.
Abstract base class for turbulence models (RAS, LES and laminar).
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
A class for handling words, derived from string.
Definition: word.H:62
Foam::fvConstraints & fvConstraints(Foam::fvConstraints::New(mesh))
Foam::fvModels & fvModels(Foam::fvModels::New(mesh))
const scalar nuEff
Calculate the matrix for the divergence of the given field and flux.
Calculate the matrix for the laplacian of the field.
label patchi
defineTypeNameAndDebug(adjustTimeStepToCombustion, 0)
addToRunTimeSelectionTable(functionObject, adjustTimeStepToCombustion, dictionary)
tmp< fvMatrix< Type > > laplacian(const VolField< Type > &vf, const word &name)
Definition: fvmLaplacian.C:47
tmp< fvMatrix< Type > > div(const surfaceScalarField &flux, const VolField< Type > &vf, const word &name)
Definition: fvmDiv.C:48
Namespace for OpenFOAM.
List< word > wordList
A List of words.
Definition: fileName.H:54
const doubleScalar e
Definition: doubleScalar.H:106
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:258
messageStream Info
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
const dimensionSet dimTime
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
const dimensionSet dimMass
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
wordList patchTypes(nPatches)
dictionary dict