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:449
Macros for easy insertion into run-time selection tables.
static fvModels & New(const word &name, const fvMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
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
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:68
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:602
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:932
Finite volume models.
Definition: fvModels.H:69
tmp< fvMatrix< Type > > source(const VolField< Type > &field) const
Return source for an equation.
Abstract base class for momentum transport 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
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
Definition: word.H:63
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
rho
Definition: pEqn.H:1
defineTypeNameAndDebug(fvMeshFunctionObject, 0)
addToRunTimeSelectionTable(functionObject, fvModel, 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
const dimensionSet & dimMass
Definition: dimensions.C:140
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
messageStream Info
const dimensionSet & dimTime
Definition: dimensions.C:142
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
wordList patchTypes(nPatches)
dictionary dict