pimpleControl.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 OpenFOAM Foundation
9  Copyright (C) 2017-2021 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 "pimpleControl.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35  defineTypeNameAndDebug(pimpleControl, 0);
36 }
37 
38 
39 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
40 
42 {
43  solutionControl::read(false);
44 
45  const dictionary pimpleDict(dict());
46 
47  solveFlow_ = pimpleDict.getOrDefault("solveFlow", true);
48  nCorrPIMPLE_ = pimpleDict.getOrDefault<label>("nOuterCorrectors", 1);
49  nCorrPISO_ = pimpleDict.getOrDefault<label>("nCorrectors", 1);
50  SIMPLErho_ = pimpleDict.getOrDefault("SIMPLErho", false);
52  pimpleDict.getOrDefault("turbOnFinalIterOnly", true);
54  pimpleDict.getOrDefault("finalOnLastPimpleIterOnly", false);
55  ddtCorr_ = pimpleDict.getOrDefault("ddtCorr", true);
56 
57  return true;
58 }
59 
60 
62 {
63  // no checks on first iteration - nothing has been calculated yet
64  if ((corr_ == 1) || residualControl_.empty() || finalIter())
65  {
66  return false;
67  }
68 
69 
70  const bool storeIni = this->storeInitialResiduals();
71 
72  bool achieved = true;
73  bool checked = false; // safety that some checks were indeed performed
74 
75  const dictionary& solverDict = mesh_.solverPerformanceDict();
76  for (const entry& solverPerfDictEntry : solverDict)
77  {
78  const word& fieldName = solverPerfDictEntry.keyword();
79  const label fieldi = applyToField(fieldName);
80 
81  if (fieldi != -1)
82  {
83  Pair<scalar> residuals = maxResidual(solverPerfDictEntry);
84 
85  checked = true;
86 
87  scalar relative = 0.0;
88  bool relCheck = false;
89 
90  const bool absCheck =
91  (residuals.last() < residualControl_[fieldi].absTol);
92 
93  if (storeIni)
94  {
95  residualControl_[fieldi].initialResidual = residuals.first();
96  }
97  else
98  {
99  const scalar iniRes =
100  (residualControl_[fieldi].initialResidual + ROOTVSMALL);
101 
102  relative = residuals.last() / iniRes;
103  relCheck = (relative < residualControl_[fieldi].relTol);
104  }
105 
106  achieved = achieved && (absCheck || relCheck);
107 
108  if (debug)
109  {
110  Info<< algorithmName_ << " loop:" << endl;
111 
112  Info<< " " << fieldName
113  << " PIMPLE iter " << corr_
114  << ": ini res = "
115  << residualControl_[fieldi].initialResidual
116  << ", abs tol = " << residuals.last()
117  << " (" << residualControl_[fieldi].absTol << ")"
118  << ", rel tol = " << relative
119  << " (" << residualControl_[fieldi].relTol << ")"
120  << endl;
121  }
122  }
123  }
124 
125  return checked && achieved;
126 }
127 
128 
129 void Foam::pimpleControl::setFirstIterFlag(const bool check, const bool force)
130 {
131  DebugInfo
132  << "corr:" << corr_
133  << " corrPISO:" << corrPISO_
134  << " corrNonOrtho:" << corrNonOrtho_
135  << endl;
136 
137  solutionControl::setFirstIterFlag(check && corrPISO_ <= 1, force);
138 }
139 
140 
141 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
142 
143 Foam::pimpleControl::pimpleControl
144 (
145  fvMesh& mesh,
146  const word& dictName,
147  const bool verbose
148 )
149 :
151  solveFlow_(true),
152  nCorrPIMPLE_(0),
153  nCorrPISO_(0),
154  corrPISO_(0),
155  SIMPLErho_(false),
156  turbOnFinalIterOnly_(true),
157  finalOnLastPimpleIterOnly_(false),
158  ddtCorr_(true),
159  converged_(false)
160 {
161  read();
162 
163  if (verbose)
164  {
165  Info<< nl << algorithmName_;
166 
167  if (nCorrPIMPLE_ > 1)
168  {
169  if (residualControl_.empty())
170  {
171  Info<< ": no residual control data found. "
172  << "Calculations will employ " << nCorrPIMPLE_
173  << " corrector loops" << nl;
174  }
175  else
176  {
177  Info<< ": max iterations = " << nCorrPIMPLE_ << nl;
178 
179  for (const fieldData& ctrl : residualControl_)
180  {
181  Info<< " field " << ctrl.name << token::TAB
182  << ": relTol " << ctrl.relTol
183  << ", tolerance " << ctrl.absTol
184  << nl;
185  }
186  }
187  }
188  else
189  {
190  Info<< ": Operating solver in PISO mode" << nl;
191  }
192 
193  Info<< endl;
194  }
195 }
196 
197 
198 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
199 
201 {
202  read();
203 
204  ++corr_;
205 
206  if (debug)
207  {
208  Info<< algorithmName_ << " loop: corr = " << corr_ << endl;
209  }
210 
211  setFirstIterFlag();
212 
213  if (corr_ == nCorrPIMPLE_ + 1)
214  {
215  if (!residualControl_.empty() && (nCorrPIMPLE_ != 1))
216  {
217  Info<< algorithmName_ << ": not converged within "
218  << nCorrPIMPLE_ << " iterations" << endl;
219  }
220 
221  corr_ = 0;
222  mesh_.data::remove("finalIteration");
223  return false;
224  }
225 
226  bool completed = false;
227  if (converged_ || criteriaSatisfied())
228  {
229  if (converged_)
230  {
231  Info<< algorithmName_ << ": converged in " << corr_ - 1
232  << " iterations" << endl;
233 
234  mesh_.data::remove("finalIteration");
235  corr_ = 0;
236  converged_ = false;
237 
238  completed = true;
239  }
240  else
241  {
242  Info<< algorithmName_ << ": iteration " << corr_ << endl;
243  storePrevIterFields();
244 
245  mesh_.data::add("finalIteration", true);
246  converged_ = true;
247  }
248  }
249  else
250  {
251  if (finalIter())
252  {
253  mesh_.data::add("finalIteration", true);
254  }
255 
256  if (corr_ <= nCorrPIMPLE_)
257  {
258  Info<< algorithmName_ << ": iteration " << corr_ << endl;
259  storePrevIterFields();
260  completed = false;
261  }
262  }
263 
264  return !completed;
265 }
266 
267 
268 // ************************************************************************* //
Foam::solutionControl::dict
virtual const dictionary dict() const
Return the solution dictionary.
Definition: solutionControl.C:300
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::pimpleControl::read
virtual bool read()
Read controls from fvSolution dictionary.
Definition: pimpleControl.C:41
Foam::pimpleControl::setFirstIterFlag
virtual void setFirstIterFlag(const bool check=true, const bool force=false)
Set the firstIteration flag on the mesh data dictionary.
Definition: pimpleControl.C:129
Foam::pimpleControl::nCorrPIMPLE_
label nCorrPIMPLE_
Maximum number of PIMPLE correctors.
Definition: pimpleControl.H:78
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::solutionControl
Base class for solution control classes.
Definition: solutionControl.H:49
Foam::pimpleControl::turbOnFinalIterOnly_
bool turbOnFinalIterOnly_
Flag to indicate whether to only solve turbulence on final iter.
Definition: pimpleControl.H:91
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
dictName
const word dictName("faMeshDefinition")
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::pimpleControl::finalOnLastPimpleIterOnly_
bool finalOnLastPimpleIterOnly_
Definition: pimpleControl.H:95
pimpleControl.H
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:181
Foam::pimpleControl::criteriaSatisfied
virtual bool criteriaSatisfied()
Return true if all convergence checks are satisfied.
Definition: pimpleControl.C:61
Foam::check
static void check(const int retVal, const char *what)
Definition: ptscotchDecomp.C:80
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::pimpleControl::solveFlow_
bool solveFlow_
Flag to indicate whether to solve for the flow.
Definition: pimpleControl.H:75
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::pimpleControl::loop
virtual bool loop()
PIMPLE loop.
Definition: pimpleControl.C:200
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::pimpleControl::ddtCorr_
bool ddtCorr_
Flag to indicate that ddtCorr should be applied; default = yes.
Definition: pimpleControl.H:98
Foam::solutionControl::read
virtual bool read()
Read controls from fvSolution dictionary.
Definition: solutionControl.C:136
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:382
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::Pair< scalar >
pimpleDict
const dictionary & pimpleDict
Definition: createRegionControls.H:3
Foam::solutionControl::fieldData
Simple convenient storage of field residuals.
Definition: solutionControl.H:56
Foam::pimpleControl::SIMPLErho_
bool SIMPLErho_
Definition: pimpleControl.H:88
Foam::token::TAB
Tab [isspace].
Definition: token.H:123
Foam::fvc::relative
tmp< surfaceScalarField > relative(const tmp< surfaceScalarField > &tphi, const volVectorField &U)
Return the given absolute flux in relative form.
Definition: fvcMeshPhi.C:155
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::pimpleControl::nCorrPISO_
label nCorrPISO_
Maximum number of PISO correctors.
Definition: pimpleControl.H:81