solutionControl.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-2016 OpenFOAM Foundation
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 "solutionControl.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34  defineTypeNameAndDebug(solutionControl, 0);
35 }
36 
37 
38 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
39 
40 bool Foam::solutionControl::read(const bool absTolOnly)
41 {
42  const dictionary solutionDict(this->dict());
43 
44  // Read solution controls
46  solutionDict.lookupOrDefault<label>("nNonOrthogonalCorrectors", 0);
48  solutionDict.lookupOrDefault("momentumPredictor", true);
49  transonic_ = solutionDict.lookupOrDefault("transonic", false);
50  consistent_ = solutionDict.lookupOrDefault("consistent", false);
51  frozenFlow_ = solutionDict.lookupOrDefault("frozenFlow", false);
52 
53  // Read residual information
54  const dictionary residualDict
55  (
56  solutionDict.subOrEmptyDict("residualControl")
57  );
58 
60 
61  for (const entry& dEntry : residualDict)
62  {
63  const word& fName = dEntry.keyword();
64  const label fieldi = applyToField(fName, false);
65  if (fieldi == -1)
66  {
67  fieldData fd;
68  fd.name = fName.c_str();
69 
70  if (absTolOnly)
71  {
72  fd.absTol = residualDict.get<scalar>(fName);
73  fd.relTol = -1;
74  fd.initialResidual = -1;
75  }
76  else if (dEntry.isDict())
77  {
78  const dictionary& fieldDict = dEntry.dict();
79  fd.absTol = fieldDict.get<scalar>("tolerance");
80  fd.relTol = fieldDict.get<scalar>("relTol");
81  fd.initialResidual = 0.0;
82  }
83  else
84  {
86  << "Residual data for " << dEntry.keyword()
87  << " must be specified as a dictionary"
88  << exit(FatalError);
89  }
90 
91  data.append(fd);
92  }
93  else
94  {
95  fieldData& fd = data[fieldi];
96  if (absTolOnly)
97  {
98  fd.absTol = residualDict.get<scalar>(fName);
99  }
100  else if (dEntry.isDict())
101  {
102  const dictionary& fieldDict = dEntry.dict();
103  fd.absTol = fieldDict.get<scalar>("tolerance");
104  fd.relTol = fieldDict.get<scalar>("relTol");
105  }
106  else
107  {
109  << "Residual data for " << dEntry.keyword()
110  << " must be specified as a dictionary"
111  << exit(FatalError);
112  }
113  }
114  }
115 
116  residualControl_.transfer(data);
117 
118  if (debug)
119  {
121  {
122  const fieldData& fd = residualControl_[i];
123  Info<< "residualControl[" << i << "]:" << nl
124  << " name : " << fd.name << nl
125  << " absTol : " << fd.absTol << nl
126  << " relTol : " << fd.relTol << nl
127  << " iniResid : " << fd.initialResidual << endl;
128  }
129  }
130 
131  return true;
132 }
133 
134 
136 {
137  return read(false);
138 }
139 
140 
142 (
143  const word& fieldName,
144  const bool useRegEx
145 ) const
146 {
147  forAll(residualControl_, i)
148  {
149  if (residualControl_[i].name.match(fieldName, !useRegEx))
150  {
151  return i;
152  }
153  }
154 
155  return -1;
156 }
157 
158 
160 {
161 // storePrevIter<label>();
162  storePrevIter<scalar>();
163  storePrevIter<vector>();
164  storePrevIter<sphericalTensor>();
165  storePrevIter<symmTensor>();
166  storePrevIter<tensor>();
167 }
168 
169 
171 (
172  const entry& solverPerfDictEntry
173 ) const
174 {
175  return maxResidual(mesh_, solverPerfDictEntry);
176 }
177 
178 
180 (
181  const bool check,
182  const bool force
183 )
184 {
185  DebugInfo
186  << "solutionControl: force:" << force
187  << " check: " << check
188  << " corr: " << corr_
189  << " corrNonOrtho:" << corrNonOrtho_
190  << endl;
191 
192  if (force || (check && corr_ <= 1 && corrNonOrtho_ == 0))
193  {
194  DebugInfo<< "solutionControl: set firstIteration flag" << endl;
195  mesh_.data::set("firstIteration", true);
196  }
197  else
198  {
199  DebugInfo<< "solutionControl: remove firstIteration flag" << endl;
200  mesh_.data::remove("firstIteration");
201  }
202 }
203 
204 
206 {
208  return false;
209 }
210 
211 
212 
213 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
214 
215 template<class Type>
217 (
218  const fvMesh& fvmesh,
219  const entry& solverPerfDictEntry,
220  Pair<scalar>& residuals
221 )
222 {
224 
225  const word& fieldName = solverPerfDictEntry.keyword();
226 
227  if (fvmesh.foundObject<fieldType>(fieldName))
228  {
229  const List<SolverPerformance<Type>> sp(solverPerfDictEntry.stream());
230 
231  residuals.first() = cmptMax(sp.first().initialResidual());
232  residuals.last() = cmptMax(sp.last().initialResidual());
233 
234  return true;
235  }
236 
237  return false;
238 }
239 
240 
242 (
243  const fvMesh& fvmesh,
244  const entry& solverPerfDictEntry
245 )
246 {
247  Pair<scalar> residuals(0,0);
248 
249  // Check with builtin short-circuit
250  const bool ok =
251  (
252  maxTypeResidual<scalar>(fvmesh, solverPerfDictEntry, residuals)
253  || maxTypeResidual<vector>(fvmesh, solverPerfDictEntry, residuals)
254  || maxTypeResidual<sphericalTensor>(fvmesh, solverPerfDictEntry, residuals)
255  || maxTypeResidual<symmTensor>(fvmesh, solverPerfDictEntry, residuals)
256  || maxTypeResidual<tensor>(fvmesh, solverPerfDictEntry, residuals)
257  );
258 
259  if (!ok && solutionControl::debug)
260  {
261  Info<<"no residual for " << solverPerfDictEntry.keyword()
262  << " on mesh " << fvmesh.name() << nl;
263  }
264 
265  return residuals;
266 }
267 
268 
269 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
270 
271 Foam::solutionControl::solutionControl(fvMesh& mesh, const word& algorithmName)
272 :
274  (
275  IOobject
276  (
277  typeName,
278  mesh.time().timeName(),
279  mesh,
280  IOobject::NO_READ,
281  IOobject::NO_WRITE
282  )
283  ),
284  mesh_(mesh),
285  residualControl_(),
286  algorithmName_(algorithmName),
287  nNonOrthCorr_(0),
288  momentumPredictor_(true),
289  transonic_(false),
290  consistent_(false),
291  frozenFlow_(false),
292  corr_(0),
293  corrNonOrtho_(0)
294 {}
295 
296 
297 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
298 
300 {
301  return mesh_.solutionDict().subOrEmptyDict(algorithmName_);
302 }
303 
304 
305 // ************************************************************************* //
Foam::solutionControl::dict
virtual const dictionary dict() const
Return the solution dictionary.
Definition: solutionControl.C:299
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::solutionControl::writeData
virtual bool writeData(Ostream &) const
Dummy write for regIOobject.
Definition: solutionControl.C:205
Foam::entry::stream
virtual ITstream & stream() const =0
Return token stream, if entry is a primitive entry.
Foam::entry::keyword
const keyType & keyword() const
Return keyword.
Definition: entry.H:187
solutionDict
fvSolution solutionDict(runTime)
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:57
Foam::solutionControl::maxTypeResidual
static bool maxTypeResidual(const fvMesh &fvmesh, const entry &solverPerfDictEntry, Pair< scalar > &residuals)
Definition: solutionControl.C:217
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::solutionControl::residualControl_
List< fieldData > residualControl_
List of residual data per field.
Definition: solutionControl.H:87
Foam::solutionControl::fieldData::absTol
scalar absTol
Definition: solutionControl.H:59
Foam::solutionControl::nNonOrthCorr_
label nNonOrthCorr_
Maximum number of non-orthogonal correctors.
Definition: solutionControl.H:96
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
solutionControl.H
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:81
Foam::dictionary::lookupOrDefault
T lookupOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.H:1241
Foam::objectRegistry::foundObject
bool foundObject(const word &name, const bool recursive=false) const
Is the named Type found?
Definition: objectRegistryTemplates.C:379
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::solutionControl::storePrevIterFields
virtual void storePrevIterFields() const
Store previous iteration fields.
Definition: solutionControl.C:159
Foam::solutionControl::setFirstIterFlag
virtual void setFirstIterFlag(const bool check=true, const bool force=false)
Set the firstIteration flag on the mesh data dictionary.
Definition: solutionControl.C:180
Foam::solutionControl::applyToField
virtual label applyToField(const word &fieldName, const bool useRegEx=true) const
Return index of field in residualControl_ if present.
Definition: solutionControl.C:142
Foam::cmptMax
void cmptMax(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:253
NotImplemented
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:419
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::string::match
bool match(const std::string &text) const
Test for equality.
Definition: stringI.H:260
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::solutionControl::momentumPredictor_
bool momentumPredictor_
Flag to indicate to solve for momentum.
Definition: solutionControl.H:99
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::solutionControl::fieldData::initialResidual
scalar initialResidual
Definition: solutionControl.H:61
Foam::solutionControl::maxResidual
static Pair< scalar > maxResidual(const fvMesh &fvmesh, const entry &dataDictEntry)
Definition: solutionControl.C:242
timeName
word timeName
Definition: getTimeIndex.H:3
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:84
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::dictionary::subOrEmptyDict
dictionary subOrEmptyDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX, const bool mandatory=false) const
Definition: dictionary.C:603
Foam::solutionControl::read
virtual bool read()
Read controls from fvSolution dictionary.
Definition: solutionControl.C:135
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::solutionControl::transonic_
bool transonic_
Flag to indicate to solve using transonic algorithm.
Definition: solutionControl.H:102
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:67
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:350
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:54
Foam::solutionControl::fieldData::relTol
scalar relTol
Definition: solutionControl.H:60
Foam::solutionControl::fieldData
Simple convenient storage of field residuals.
Definition: solutionControl.H:56
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:102
Foam::solutionControl::consistent_
bool consistent_
Flag to indicate to relax pressure using the.
Definition: solutionControl.H:106
Foam::solutionControl::frozenFlow_
bool frozenFlow_
Flag to indicate that the flow system of equations should not.
Definition: solutionControl.H:110
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::solutionControl::fieldData::name
wordRe name
Definition: solutionControl.H:58
Foam::GeometricField< Type, fvPatchField, volMesh >
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:54
Foam::fvMesh::name
const word & name() const
Return reference to name.
Definition: fvMesh.H:266